自定義View進(jìn)階篇《五》——Path之基本操作

一、Path常用方法表

為了兼容性(偷懶) 本表格中去除了部分API21(即安卓版本5.0)以上才添加的方法。


二、Path詳解

請(qǐng)關(guān)閉硬件加速,以免引起不必要的問題!
請(qǐng)關(guān)閉硬件加速,以免引起不必要的問題!
請(qǐng)關(guān)閉硬件加速,以免引起不必要的問題!
在AndroidMenifest文件中application節(jié)點(diǎn)下添上 android:hardwareAccelerated=”false”以關(guān)閉整個(gè)應(yīng)用的硬件加速。

Path作用

本次特地開了一篇詳細(xì)講解Path,為什么要單獨(dú)摘出來呢,這是因?yàn)镻ath在2D繪圖中是一個(gè)很重要的東西。

在前面我們講解的所有繪制都是簡單圖形(如 矩形 圓 圓弧等),而對(duì)于那些復(fù)雜一點(diǎn)的圖形則沒法去繪制(如繪制一個(gè)心形 正多邊形 五角星等),而使用Path不僅能夠繪制簡單圖形,也可以繪制這些比較復(fù)雜的圖形。另外,根據(jù)路徑繪制文本和剪裁畫布都會(huì)用到Path。

Path含義

Path封裝了由直線和曲線(二次,三次貝塞爾曲線)構(gòu)成的幾何路徑。你能用Canvas中的drawPath來把這條路徑畫出來(同樣支持Paint的不同繪制模式),也可以用于剪裁畫布和根據(jù)路徑繪制文字。我們有時(shí)會(huì)用Path來描述一個(gè)圖像的輪廓,所以也會(huì)稱為輪廓線(輪廓線僅是Path的一種使用方法,兩者并不等價(jià))
另外路徑有開放和封閉的區(qū)別。


Path使用方法詳解

第1組: moveTo、 setLastPoint、 lineTo 和 close
由于Path的有些知識(shí)點(diǎn)無法單獨(dú)來講,所以本次采取了一次講一組方法。

按照慣例,先創(chuàng)建畫筆:

Paint mPaint = new Paint();             // 創(chuàng)建畫筆
mPaint.setColor(Color.BLACK);           // 畫筆顏色 - 黑色
mPaint.setStyle(Paint.Style.STROKE);    // 填充模式 - 描邊
mPaint.setStrokeWidth(10);              // 邊框?qū)挾?- 10

lineTo:

方法預(yù)覽:

public void lineTo (float x, float y)

首先講解的的LineTo,為啥先講解這個(gè)呢?

是因?yàn)閙oveTo、 setLastPoint、 close都無法直接看到效果,借助有具現(xiàn)化效果的lineTo才能讓這些方法現(xiàn)出原形。

lineTo很簡單,只有一個(gè)方法,作用也很容易理解,line嘛,顧名思義就是一條線。

俗話(數(shù)學(xué)書上)說,兩點(diǎn)確定一條直線,但是看參數(shù)明顯只給了一個(gè)點(diǎn)的坐標(biāo)吧(這不按常理出牌啊)。

再仔細(xì)一看,這個(gè)lineTo除了line外還有一個(gè)to呢,to翻譯過來就是“至”,到某個(gè)地方的意思,lineTo難道是指從某個(gè)點(diǎn)到參數(shù)坐標(biāo)點(diǎn)之間連一條線?

沒錯(cuò),你猜對(duì)了,但是這某個(gè)點(diǎn)又是哪里呢?

前面我們提到過Path可以用來描述一個(gè)圖像的輪廓,圖像的輪廓通常都是用一條線構(gòu)成的,所以這里的某個(gè)點(diǎn)就是上次操作結(jié)束的點(diǎn),如果沒有進(jìn)行過操作則默認(rèn)點(diǎn)為坐標(biāo)原點(diǎn)。

那么我們就來試一下:

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心(寬高數(shù)據(jù)在onSizeChanged中獲取)

Path path = new Path();                     // 創(chuàng)建Path

path.lineTo(200, 200);                      // lineTo
path.lineTo(200,0);

canvas.drawPath(path, mPaint);              // 繪制Path

在示例中我們調(diào)用了兩次lineTo,第一次由于之前沒有過操作,所以默認(rèn)點(diǎn)就是坐標(biāo)原點(diǎn)O,結(jié)果就是坐標(biāo)原點(diǎn)O到A(200,200)之間連直線(用藍(lán)色圈1標(biāo)注)。

第二次lineTo的時(shí)候,由于上次的結(jié)束位置是A(200,200),所以就是A(200,200)到B(200,0)之間的連線(用藍(lán)色圈2標(biāo)注)。

moveTo 和 setLastPoint:

方法預(yù)覽:

// moveTo
public void moveTo (float x, float y)

// setLastPoint
public void setLastPoint (float dx, float dy)

這兩個(gè)方法雖然在作用上有相似之處,但實(shí)際上卻是完全不同的兩個(gè)東東,具體參照下表:



廢話不多說,直接上代碼:

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心

Path path = new Path();                     // 創(chuàng)建Path

path.lineTo(200, 200);                      // lineTo

path.moveTo(200,100);                       // moveTo

path.lineTo(200,0);                         // lineTo

canvas.drawPath(path, mPaint);              // 繪制Path

這個(gè)和上面演示lineTo的方法類似,只不過在兩個(gè)lineTo之間添加了一個(gè)moveTo。
moveTo只改變下次操作的起點(diǎn),在執(zhí)行完第一次LineTo的時(shí)候,本來的默認(rèn)點(diǎn)位置是A(200,200),但是moveTo將其改變成為了C(200,100),所以在第二次調(diào)用lineTo的時(shí)候就是連接C(200,100) 到 B(200,0) 之間的直線(用藍(lán)色圈2標(biāo)注)。
下面是setLastPoint的示例:

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心

Path path = new Path();                     // 創(chuàng)建Path

path.lineTo(200, 200);                      // lineTo

path.setLastPoint(200,100);                 // setLastPoint

path.lineTo(200,0);                         // lineTo

canvas.drawPath(path, mPaint);              // 繪制Path

setLastPoint是重置上一次操作的最后一個(gè)點(diǎn),在執(zhí)行完第一次的lineTo的時(shí)候,最后一個(gè)點(diǎn)是A(200,200),而setLastPoint更改最后一個(gè)點(diǎn)為C(200,100),所以在實(shí)際執(zhí)行的時(shí)候,第一次的lineTo就不是從原點(diǎn)O到A(200,200)的連線了,而變成了從原點(diǎn)O到C(200,100)之間的連線了。

在執(zhí)行完第一次lineTo和setLastPoint后,最后一個(gè)點(diǎn)的位置是C(200,100),所以在第二次調(diào)用lineTo的時(shí)候就是C(200,100) 到 B(200,0) 之間的連線(用藍(lán)色圈2標(biāo)注)。

close

方法預(yù)覽:

public void close ()

close方法用于連接當(dāng)前最后一個(gè)點(diǎn)和最初的一個(gè)點(diǎn)(如果兩個(gè)點(diǎn)不重合的話),最終形成一個(gè)封閉的圖形。

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心

Path path = new Path();                     // 創(chuàng)建Path

path.lineTo(200, 200);                      // lineTo

path.lineTo(200,0);                         // lineTo

path.close();                               // close

canvas.drawPath(path, mPaint);              // 繪制Path

很明顯,兩個(gè)lineTo分別代表第1和第2條線,而close在此處的作用就算連接了B(200,0)點(diǎn)和原點(diǎn)O之間的第3條線,使之形成一個(gè)封閉的圖形。
注意:close的作用是封閉路徑,與連接當(dāng)前最后一個(gè)點(diǎn)和第一個(gè)點(diǎn)并不等價(jià)。如果連接了最后一個(gè)點(diǎn)和第一個(gè)點(diǎn)仍然無法形成封閉圖形,則close什么 也不做。

第2組: addXxx與arcTo

這次內(nèi)容主要是在Path中添加基本圖形,重點(diǎn)區(qū)分addArc與arcTo。

第一類(基本形狀)

方法預(yù)覽:

// 第一類(基本形狀)

// 圓形
public void addCircle (float x, float y, float radius, Path.Direction dir)
// 橢圓
public void addOval (RectF oval, Path.Direction dir)
// 矩形
public void addRect (float left, float top, float right, float bottom, Path.Direction dir)
public void addRect (RectF rect, Path.Direction dir)
// 圓角矩形
public void addRoundRect (RectF rect, float[] radii, Path.Direction dir)
public void addRoundRect (RectF rect, float rx, float ry, Path.Direction dir)

仔細(xì)觀察一下第一類是方法,無一例外,在最后都有一個(gè) Path.Direction,這是一個(gè)什么神奇的東東?
Direction的意思是 方向,趨勢。 點(diǎn)進(jìn)去看一下會(huì)發(fā)現(xiàn)Direction是一個(gè)枚舉(Enum)類型,里面只有兩個(gè)枚舉常量,如下:



先偷偷劇透一下這個(gè)順時(shí)針和逆時(shí)針的作用。



這個(gè)先劇透這么多,至于對(duì)閉合順序有啥影響,圖形的渲染等問題等請(qǐng)慢慢看下去

咱們先研究確定閉合順序的問題,添加一個(gè)矩形試試看:

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心

Path path = new Path();

path.addRect(-200,-200,200,200, Path.Direction.CW);

canvas.drawPath(path,mPaint);

將上面代碼的CW改為CCW再運(yùn)行一次。接下來就是見證奇跡的時(shí)刻,兩次運(yùn)行結(jié)果一模一樣,有木有很神奇!(神奇?zhèn)€毛啊??????????)
其實(shí)啊,這個(gè)東東是自帶隱身技能的,想要讓它現(xiàn)出原形,就要用到咱們剛剛學(xué)到的setLastPoint(重置當(dāng)前最后一個(gè)點(diǎn)的位置)。

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心

Path path = new Path();

path.addRect(-200,-200,200,200, Path.Direction.CW);

path.setLastPoint(-300,300);                // <-- 重置最后一個(gè)點(diǎn)的位置

canvas.drawPath(path,mPaint);

可以明顯看到,圖形發(fā)生了奇怪的變化。為何會(huì)如此呢?

我們先分析一下,繪制一個(gè)矩形(僅繪制邊線),實(shí)際上只需要進(jìn)行四次lineTo操作就行了,也就是說,只需要知道4個(gè)點(diǎn)的坐標(biāo),然后使用moveTo到第一個(gè)點(diǎn),之后依次lineTo就行了(從上面的測試可以看出,在實(shí)際繪制中也確實(shí)是這么干的)。

可是為什么要這么做呢?確定一個(gè)矩形最少需要兩個(gè)點(diǎn)(對(duì)角線的兩個(gè)點(diǎn)),根據(jù)這兩個(gè)點(diǎn)的坐標(biāo)直接算出四條邊然后畫出來不就行了,干嘛還要先計(jì)算出四個(gè)點(diǎn)坐標(biāo),之后再連直線呢?

這個(gè)就要涉及一些path的存儲(chǔ)問題了,前面在path中的定義中說過,Path是封裝了由直線和曲線(二次,三次貝塞爾曲線)構(gòu)成的幾何路徑。其中曲線部分用的是貝塞爾曲線,稍后再講。 然而除了曲線部分就只剩下直線了,對(duì)于直線的存儲(chǔ)最簡單的就是記錄坐標(biāo)點(diǎn),然后直接連接各個(gè)點(diǎn)就行了。雖然記錄矩形只需要兩個(gè)點(diǎn),但是如果只用兩個(gè)點(diǎn)來記錄一個(gè)矩形的話,就要額外增加一個(gè)標(biāo)志位來記錄這是一個(gè)矩形,顯然對(duì)于存儲(chǔ)和解析都是很不劃算的事情,將矩形轉(zhuǎn)換為直線,為的就是存儲(chǔ)記錄方便。

扯了這么多,該回歸正題了,就是我們的順時(shí)針和逆時(shí)針在這里是干啥的?

圖形在實(shí)際記錄中就是記錄各個(gè)的點(diǎn),對(duì)于一個(gè)圖形來說肯定有多個(gè)點(diǎn),既然有這么多的點(diǎn),肯定就需要一個(gè)先后順序,這里順時(shí)針和逆時(shí)針就是用來確定記錄這些點(diǎn)的順序的。

對(duì)于上面這個(gè)矩形來說,我們采用的是順時(shí)針(CW),所以記錄的點(diǎn)的順序就是 A -> B -> C -> D. 最后一個(gè)點(diǎn)就是D,我們這里使用setLastPoint改變最后一個(gè)點(diǎn)的位置實(shí)際上是改變了D的位置。

理解了上面的原理之后,設(shè)想如果我們將順時(shí)針改為逆時(shí)針(CCW),則記錄點(diǎn)的順序應(yīng)該就是 A -> D -> C -> B, 再使用setLastPoint則改變的是B的位置,我們試試看結(jié)果和我們的猜想是否一致:

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心

Path path = new Path();

path.addRect(-200,-200,200,200, Path.Direction.CCW);

path.setLastPoint(-300,300);                // <-- 重置最后一個(gè)點(diǎn)的位置

canvas.drawPath(path,mPaint);

通過驗(yàn)證發(fā)現(xiàn),發(fā)現(xiàn)結(jié)果和我們猜想的一樣,但是還有一個(gè)潛藏的問題不曉得大家可否注意到。我們用兩個(gè)點(diǎn)的坐標(biāo)確定了一個(gè)矩形,矩形起始點(diǎn)(A)就是我們指定的第一個(gè)點(diǎn)的坐標(biāo)。

需要注意的是,交換坐標(biāo)點(diǎn)的順序可能就會(huì)影響到某些繪制內(nèi)容哦,例如上面的例子,你可以嘗試交換兩個(gè)坐標(biāo)點(diǎn),或者指定另外兩個(gè)點(diǎn)來作為參數(shù),雖然指定的是同一個(gè)矩形,但實(shí)際繪制出來是不同的哦。
參數(shù)中點(diǎn)的順序很重要!
參數(shù)中點(diǎn)的順序很重要!
參數(shù)中點(diǎn)的順序很重要!

重要的話說三遍,本次是用矩形作為例子的,其他的幾個(gè)圖形基本上都包含了曲線,詳情參見后續(xù)的貝塞爾曲線部分。

重要的話說三遍,本次是用矩形作為例子的,其他的幾個(gè)圖形基本上都包含了曲線,詳情參見后續(xù)的貝塞爾曲線部分。

第二類(Path)

方法預(yù)覽:

// 第二類(Path)
// path
public void addPath (Path src)
public void addPath (Path src, float dx, float dy)
public void addPath (Path src, Matrix matrix)

這個(gè)相對(duì)比較簡單,也很容易理解,就是將兩個(gè)Path合并成為一個(gè)。

第三個(gè)方法是將src添加到當(dāng)前path之前先使用Matrix進(jìn)行變換。

第二個(gè)方法比第一個(gè)方法多出來的兩個(gè)參數(shù)是將src進(jìn)行了位移之后再添加進(jìn)當(dāng)前path中。
示例:

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻轉(zhuǎn)y坐標(biāo)軸

Path path = new Path();
Path src = new Path();

path.addRect(-200,-200,200,200, Path.Direction.CW);
src.addCircle(0,0,100, Path.Direction.CW);

path.addPath(src,0,200);

mPaint.setColor(Color.BLACK);           // 繪制合并后的路徑
canvas.drawPath(path,mPaint);

首先我們新建地方兩個(gè)Path(矩形和圓形)中心都是坐標(biāo)原點(diǎn),我們在將包含圓形的path添加到包含矩形的path之前將其進(jìn)行移動(dòng)了一段距離,最終繪制出來的效果就如上面所示。

第三類(addArc與arcTo)

方法預(yù)覽:

// 第三類(addArc與arcTo)

// addArc
public void addArc (RectF oval, float startAngle, float sweepAngle)
// arcTo
public void arcTo (RectF oval, float startAngle, float sweepAngle)
public void arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)

參數(shù)表:


PS: sweepAngle取值范圍是 [-360, 360),不包括360,當(dāng) >= 360 或者 < -360 時(shí)將不會(huì)繪制任何內(nèi)容, 對(duì)于360,你可以用一個(gè)接近的值替代,例如: 359.99。

從名字就可以看出,這兩個(gè)方法都是與圓弧相關(guān)的,作用都是添加一個(gè)圓弧到path中,但既然存在兩個(gè)方法,兩者之間肯定是有區(qū)別的:



可以看到addArc有1個(gè)方法(實(shí)際上是兩個(gè)的,但另一個(gè)重載方法是API21添加的), 而arcTo有2個(gè)方法,其中一個(gè)最后多了一個(gè)布爾類型的變量forceMoveTo。

forceMoveTo是什么作用呢?

這個(gè)變量意思為“是否強(qiáng)制使用moveTo”,也就是說,是否使用moveTo將變量移動(dòng)到圓弧的起點(diǎn)位移,也就意味著:



示例(addArc):

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻轉(zhuǎn)y坐標(biāo)軸

Path path = new Path();
path.lineTo(100,100);

RectF oval = new RectF(0,0,300,300);

path.addArc(oval,0,270);
// path.arcTo(oval,0,270,true);             // <-- 和上面一句作用等價(jià)

canvas.drawPath(path,mPaint);

示例(arcTo):

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻轉(zhuǎn)y坐標(biāo)軸

Path path = new Path();
path.lineTo(100,100);

RectF oval = new RectF(0,0,300,300);

path.arcTo(oval,0,270);
// path.arcTo(oval,0,270,false);             // <-- 和上面一句作用等價(jià)

canvas.drawPath(path,mPaint);

第3組:isEmpty、 isRect、isConvex、 set 和 offset

這一組比較簡單,稍微說一下就可以了。

isEmpty

方法預(yù)覽:

public boolean isEmpty ()

判斷path中是否包含內(nèi)容。

Path path = new Path();
Log.e("1",path.isEmpty()+"");

path.lineTo(100,100);
Log.e("2",path.isEmpty()+"");

log輸出結(jié)果:

com.sloop.canvas E/1: true
com.sloop.canvas E/2: false

isRect

方法預(yù)覽:

public boolean isRect (RectF rect)

判斷path是否是一個(gè)矩形,如果是一個(gè)矩形的話,會(huì)將矩形的信息存放進(jìn)參數(shù)rect中。

path.lineTo(0,400);
path.lineTo(400,400);
path.lineTo(400,0);
path.lineTo(0,0);

RectF rect = new RectF();
boolean b = path.isRect(rect);
Log.e("Rect","isRect:"+b+"| left:"+rect.left+"| top:"+rect.top+"| right:"+rect.right+"| bottom:"+rect.bottom);

log 輸出結(jié)果:

com.sloop.canvas E/Rect: isRect:true| left:0.0| top:0.0| right:400.0| bottom:400.0

set

方法預(yù)覽:

public void set (Path src)

將新的path賦值到現(xiàn)有path。

canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻轉(zhuǎn)y坐標(biāo)軸

Path path = new Path();                     // path添加一個(gè)矩形
path.addRect(-200,-200,200,200, Path.Direction.CW);

Path src = new Path();                      // src添加一個(gè)圓
src.addCircle(0,0,100, Path.Direction.CW);

path.set(src);                              // 大致相當(dāng)于 path = src;

canvas.drawPath(path,mPaint);

offset

方法預(yù)覽:

public void offset (float dx, float dy)
public void offset (float dx, float dy, Path dst)

這個(gè)的作用也很簡單,就是對(duì)path進(jìn)行一段平移,它和Canvas中的translate作用很像,但Canvas作用于整個(gè)畫布,而path的offset只作用于當(dāng)前path。
但是第二個(gè)方法最后怎么會(huì)有一個(gè)path作為參數(shù)?

其實(shí)第二個(gè)方法中最后的參數(shù)das是存儲(chǔ)平移后的path的。


canvas.translate(mWidth / 2, mHeight / 2);  // 移動(dòng)坐標(biāo)系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻轉(zhuǎn)y坐標(biāo)軸

Path path = new Path();                     // path中添加一個(gè)圓形(圓心在坐標(biāo)原點(diǎn))
path.addCircle(0,0,100, Path.Direction.CW);

Path dst = new Path();                      // dst中添加一個(gè)矩形
dst.addRect(-200,-200,200,200, Path.Direction.CW);

path.offset(300,0,dst);                     // 平移

canvas.drawPath(path,mPaint);               // 繪制path

mPaint.setColor(Color.BLUE);                // 更改畫筆顏色

canvas.drawPath(dst,mPaint);                // 繪制dst

從運(yùn)行效果圖可以看出,雖然我們在dst中添加了一個(gè)矩形,但是并沒有表現(xiàn)出來,所以,當(dāng)dst中存在內(nèi)容時(shí),dst中原有的內(nèi)容會(huì)被清空,而存放平移后的path。

三、總結(jié)

本想一篇把path寫完,但是萬萬沒想到居然扯了這么多。本篇中講解的是直線部分和一些常用方法,下一篇將著重講解貝塞爾曲線和自相交圖形渲染等相關(guān)問題,敬請(qǐng)期待哦。

學(xué)完本篇之后又解鎖了新的境界,可以看看這位大神的文章 Android雷達(dá)圖(蜘蛛網(wǎng)圖)繪制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評(píng)論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,744評(píng)論 3 421
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,879評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,935評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,325評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,534評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,084評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,892評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,067評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,322評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評(píng)論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評(píng)論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,800評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,084評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容