安卓自定義View進(jìn)階-Canvas之繪制圖形

在上一篇自定義View分類與流程中我們了解自定義View相關(guān)的基本知識,不過,這些東西依舊還是理論身弊,并不能拿來(zhuang)用(B), 這一次我們就了解一些能(zhaung)用(B)的東西丸边。

在本篇文章中儿普,我們先了解Canvas的基本用法贮竟,最后用一個小示例來結(jié)束本次教程。

一.Canvas簡介

Canvas我們可以稱之為畫布较剃,能夠在上面繪制各種東西咕别,是安卓平臺2D圖形繪制的基礎(chǔ),非常強(qiáng)大写穴。

一般來說惰拱,比較基礎(chǔ)的東西有兩大特點:

  • 1.可操作性強(qiáng):由于這些是構(gòu)成上層的基礎(chǔ),所以可操作性必然十分強(qiáng)大啊送。
  • 2.比較難用:各種方法太過基礎(chǔ)偿短,想要完美的將這些操作組合起來有一定難度。

不過不必?fù)?dān)心馋没,本系列文章不僅會介紹到Canvas的操作方法昔逗,還會簡單介紹一些設(shè)計思路和技巧。

二.Canvas的常用操作速查表

操作類型 相關(guān)API 備注
繪制顏色 drawColor, drawRGB, drawARGB 使用單一顏色填充整個畫布
繪制基本形狀 drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc 依次為 點篷朵、線勾怒、矩形婆排、圓角矩形、橢圓笔链、圓段只、圓弧
繪制圖片 drawBitmap, drawPicture 繪制位圖和圖片
繪制文本 drawText, drawPosText, drawTextOnPath 依次為 繪制文字、繪制文字時指定每個文字位置鉴扫、根據(jù)路徑繪制文字
繪制路徑 drawPath 繪制路徑赞枕,繪制貝塞爾曲線時也需要用到該函數(shù)
頂點操作 drawVertices, drawBitmapMesh 通過對頂點操作可以使圖像形變,drawVertices直接對畫布作用坪创、 drawBitmapMesh只對繪制的Bitmap作用
畫布剪裁 clipPath, clipRect 設(shè)置畫布的顯示區(qū)域
畫布快照 save, restore, saveLayerXxx, restoreToCount, getSaveCount 依次為 保存當(dāng)前狀態(tài)炕婶、 回滾到上一次保存的狀態(tài)、 保存圖層狀態(tài)误堡、 回滾到指定狀態(tài)古话、 獲取保存次數(shù)
畫布變換 translate, scale, rotate, skew 依次為 位移、縮放锁施、 旋轉(zhuǎn)陪踩、錯切
Matrix(矩陣) getMatrix, setMatrix, concat 實際上畫布的位移,縮放等操作的都是圖像矩陣Matrix悉抵, 只不過Matrix比較難以理解和使用肩狂,故封裝了一些常用的方法。

PS: Canvas常用方法在上面表格中已經(jīng)全部列出了姥饰,當(dāng)然還存在一些其他的方法未列出傻谁,具體可以參考官方文檔 Canvas


三.Canvas詳解

本篇內(nèi)容主要講解如何利用Canvas繪制基本圖形。

繪制顏色:

繪制顏色是填充整個畫布列粪,常用于繪制底色审磁。

canvas.drawColor(Color.BLUE); //繪制藍(lán)色

關(guān)于顏色的更多資料請參考基礎(chǔ)篇_顏色


創(chuàng)建畫筆:

要想繪制內(nèi)容,首先需要先創(chuàng)建一個畫筆岂座,如下:

// 1.創(chuàng)建一個畫筆
private Paint mPaint = new Paint();

// 2.初始化畫筆
private void initPaint() {
    mPaint.setColor(Color.BLACK);       //設(shè)置畫筆顏色
    mPaint.setStyle(Paint.Style.FILL);  //設(shè)置畫筆模式為填充
    mPaint.setStrokeWidth(10f);         //設(shè)置畫筆寬度為10px
}

// 3.在構(gòu)造函數(shù)中初始化
public SloopView(Context context, AttributeSet attrs) {
   super(context, attrs);
   initPaint();
}

在創(chuàng)建完畫筆之后态蒂,就可以在Canvas中繪制各種內(nèi)容了。


繪制點:

可以繪制一個點费什,也可以繪制一組點钾恢,如下:

canvas.drawPoint(200, 200, mPaint);     //在坐標(biāo)(200,200)位置繪制一個點
canvas.drawPoints(new float[]{          //繪制一組點,坐標(biāo)位置由float數(shù)組指定
      500,500,
      500,600,
      500,700
},mPaint);

關(guān)于坐標(biāo)原點默認(rèn)在左上角鸳址,水平向右為x軸增大方向瘩蚪,豎直向下為y軸增大方向。

更多參考這里 基礎(chǔ)篇_坐標(biāo)系


繪制直線:

繪制直線需要兩個點稿黍,初始點和結(jié)束點疹瘦,同樣繪制直線也可以繪制一條或者繪制一組:

canvas.drawLine(300,300,500,600,mPaint);    // 在坐標(biāo)(300,300)(500,600)之間繪制一條直線
canvas.drawLines(new float[]{               // 繪制一組線 每四數(shù)字(兩個點的坐標(biāo))確定一條線
    100,200,200,200,
    100,300,200,300
},mPaint);

繪制矩形:

確定確定一個矩形最少需要四個數(shù)據(jù),就是對角線的兩個點的坐標(biāo)值闻察,這里一般采用左上角和右下角的兩個點的坐標(biāo)拱礁。

關(guān)于繪制矩形琢锋,Canvas提供了三種重載方法,第一種就是提供四個數(shù)值(矩形左上角和右下角兩個點的坐標(biāo))來確定一個矩形進(jìn)行繪制呢灶。
其余兩種是先將矩形封裝為Rect或RectF(實際上仍然是用兩個坐標(biāo)點來確定的矩形)吴超,然后傳遞給Canvas繪制,如下:

// 第一種
canvas.drawRect(100,100,800,400,mPaint);

// 第二種
Rect rect = new Rect(100,100,800,400);
canvas.drawRect(rect,mPaint);

// 第三種
RectF rectF = new RectF(100,100,800,400);
canvas.drawRect(rectF,mPaint);

以上三種方法所繪制出來的結(jié)果是完全一樣的鸯乃。

看到這里,相信很多觀眾會產(chǎn)生一個疑問鲸阻,為什么會有Rect和RectF兩種?兩者有什么區(qū)別嗎缨睡?

答案當(dāng)然是存在區(qū)別的鸟悴,兩者最大的區(qū)別就是精度不同,Rect是int(整形)的奖年,而RectF是float(單精度浮點型)的细诸。除了精度不同,兩種提供的方法也稍微存在差別陋守,在這里我們暫時無需關(guān)注震贵,想了解更多參見官方文檔 RectRectF


繪制圓角矩形:

繪制圓角矩形也提供了兩種重載方式,如下:

// 第一種
RectF rectF = new RectF(100,100,800,400);
canvas.drawRoundRect(rectF,30,30,mPaint);

// 第二種
canvas.drawRoundRect(100,100,800,400,30,30,mPaint);

上面兩種方法繪制效果也是一樣的水评,但鑒于第二種方法在API21的時候才添加上猩系,所以我們一般使用的都是第一種。

下面簡單解析一下圓角矩形的幾個必要的參數(shù)的意思中燥。

很明顯可以看出寇甸,第二種方法前四個參數(shù)和第一種方法的RectF作用是一樣的,都是為了確定一個矩形疗涉,最后一個參數(shù)Paint是畫筆拿霉,無需多說,與矩形相比咱扣,圓角矩形多出來了兩個參數(shù)rx 和 ry友浸,這兩個參數(shù)是干什么的呢?

稍微分析一下偏窝,既然是圓角矩形,他的角肯定是圓弧(圓形的一部分)武学,我們一般用什么確定一個圓形呢祭往?

答案是圓心 和 半徑,其中圓心用于確定位置火窒,而半徑用于確定大小硼补。

由于矩形位置已經(jīng)確定,所以其邊角位置也是確定的熏矿,那么確定位置的參數(shù)就可以省略已骇,只需要用半徑就能描述一個圓弧了离钝。

但是,半徑只需要一個參數(shù)褪储,但這里怎么會有兩個呢卵渴?

好吧,讓你發(fā)現(xiàn)了鲤竹,這里圓角矩形的角實際上不是一個正圓的圓弧,而是橢圓的圓弧,這里的兩個參數(shù)實際上是橢圓的兩個半徑黔州,他們看起來個如下圖:

紅線標(biāo)注的 rx 與 ry 就是兩個半徑苫纤,也就是相比繪制矩形多出來的那兩個參數(shù)。

我們了解到原理后吱肌,就可以為所欲為了痘拆,通過計算可知我們上次繪制的矩形寬度為700,高度為300氮墨,當(dāng)你讓 rx大于350(寬度的一半)纺蛆, ry大于150(高度的一半) 時奇跡就出現(xiàn)了, 你會發(fā)現(xiàn)圓角矩形變成了一個橢圓勇边, 他們畫出來是這樣的 ( 為了方便確認(rèn)我更改了畫筆顏色犹撒, 同時繪制出了矩形和圓角矩形 ):

// 矩形
RectF rectF = new RectF(100,100,800,400);  

// 繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF,mPaint);

// 繪制圓角矩形
mPaint.setColor(Color.BLUE);
canvas.drawRoundRect(rectF,700,400,mPaint);

其中灰色部分是我們所選定的矩形,而里面的圓角矩形則變成了一個橢圓粒褒,實際上在rx為寬度的一半识颊,ry為高度的一半時,剛好是一個橢圓奕坟,通過上面我們分析的原理推算一下就能得到祥款,而當(dāng)rx大于寬度的一半,ry大于高度的一半時月杉,實際上是無法計算出圓弧的刃跛,所以drawRoundRect對大于該數(shù)值的參數(shù)進(jìn)行了限制(修正),凡是大于一半的參數(shù)均按照一半來處理苛萎。


繪制橢圓:

相對于繪制圓角矩形桨昙,繪制橢圓就簡單的多了,因為他只需要一個矩形矩形作為參數(shù):

// 第一種
RectF rectF = new RectF(100,100,800,400);
canvas.drawOval(rectF,mPaint);

// 第二種
canvas.drawOval(100,100,800,400,mPaint);

同樣腌歉,以上兩種方法效果完全一樣蛙酪,但一般使用第一種。

繪制橢圓實際上就是繪制一個矩形的內(nèi)切圖形翘盖,原理如下桂塞,就不多說了:

PS: 如果你傳遞進(jìn)來的是一個長寬相等的矩形(即正方形),那么繪制出來的實際上就是一個圓馍驯。


繪制圓:

繪制圓形也比較簡單, 如下:

canvas.drawCircle(500,500,400,mPaint);  // 繪制一個圓心坐標(biāo)在(500,500)阁危,半徑為400 的圓玛痊。

繪制圓形有四個參數(shù),前兩個是圓心坐標(biāo)狂打,第三個是半徑擂煞,最后一個是畫筆。


繪制圓涣飧浮:

繪制圓弧就比較神奇一點了颈娜,為了理解這個比較神奇的東西,我們先看一下它需要的幾個參數(shù):

// 第一種
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){}
    
// 第二種
public void drawArc(float left, float top, float right, float bottom, float startAngle,
            float sweepAngle, boolean useCenter, @NonNull Paint paint) {}

從上面可以看出浙宜,相比于繪制橢圓官辽,繪制圓弧還多了三個參數(shù):

startAngle  // 開始角度
sweepAngle  // 掃過角度
useCenter   // 是否使用中心

通過字面意思我們基本能猜測出來前兩個參數(shù)(startAngle, sweepAngel)的作用粟瞬,就是確定角度的起始位置和掃過角度同仆, 不過第三個參數(shù)是干嘛的?試一下就知道了,上代碼:

RectF rectF = new RectF(100,100,800,400);
// 繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF,mPaint);

// 繪制圓弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF,0,90,false,mPaint);

//-------------------------------------

RectF rectF2 = new RectF(100,600,800,900);
// 繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF2,mPaint);

// 繪制圓弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF2,0,90,true,mPaint);

上述代碼實際上是繪制了一個起始角度為0度裙品,掃過90度的圓弧俗批,兩者的區(qū)別就是是否使用了中心點,結(jié)果如下:

可以發(fā)現(xiàn)使用了中心點之后繪制出來類似于一個扇形市怎,而不使用中心點則是圓弧起始點和結(jié)束點之間的連線加上圓弧圍成的圖形岁忘。這樣中心點這個參數(shù)的作用就很明顯了,不必多說想必大家試一下就明白了区匠。 另外可以關(guān)于角度可以參考一下這篇文章: 角度與弧度

相比于使用橢圓干像,我們還是使用正圓比較多的,使用正圓展示一下效果:

RectF rectF = new RectF(100,100,600,600);
// 繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF,mPaint);

// 繪制圓弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF,0,90,false,mPaint);

//-------------------------------------

RectF rectF2 = new RectF(100,700,600,1200);
// 繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF2,mPaint);

// 繪制圓弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF2,0,90,true,mPaint);

簡要介紹Paint

看了上面這么多驰弄,相信有一部分人會產(chǎn)生一個疑問麻汰,如果我想繪制一個圓,只要邊不要里面的顏色怎么辦戚篙?

很簡單五鲫,繪制的基本形狀由Canvas確定,但繪制出來的顏色,具體效果則由Paint確定岔擂。

如果你注意到了的話位喂,在一開始我們設(shè)置畫筆樣式的時候是這樣的:

mPaint.setStyle(Paint.Style.FILL);  //設(shè)置畫筆模式為填充

為了展示方便,容易看出效果乱灵,之前使用的模式一直為填充模式忆某,實際上畫筆有三種模式,如下:

STROKE                //描邊
FILL                  //填充
FILL_AND_STROKE       //描邊加填充

為了區(qū)分三者效果我們做如下實驗:

Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(40);     //為了實驗效果明顯阔蛉,特地設(shè)置描邊寬度非常大

// 描邊
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(200,200,100,paint);

// 填充
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(200,500,100,paint);

// 描邊加填充
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(200, 800, 100, paint);

一圖勝千言,通過以上實驗我們可以比較明顯的看出三種模式的區(qū)別癞埠,如果只需要邊緣不需要填充內(nèi)容的話只需要設(shè)置模式為描邊(STROKE)即可状原。

其實關(guān)于Paint的內(nèi)容也是有不少的聋呢,這些只是冰山一角,在后續(xù)內(nèi)容中會詳細(xì)的講解Paint颠区。


小示例

簡要介紹畫布的操作:

畫布操作詳細(xì)內(nèi)容會在下一篇文章中講解, 不是本文重點削锰,但以下示例中可能會用到,所以此處簡要介紹一下毕莱。

相關(guān)操作 簡要介紹
save 保存當(dāng)前畫布狀態(tài)
restore 回滾到上一次保存的狀態(tài)
translate 相對于當(dāng)前位置位移
rotate 旋轉(zhuǎn)

制作一個餅狀圖

在展示百分比數(shù)據(jù)的時候經(jīng)常會用到餅狀圖器贩,像這樣:

簡單分析

其實根據(jù)我們上面的知識已經(jīng)能自己制作一個餅狀圖了。不過制作東西最重要的不是制作結(jié)果朋截,而是制作思路蛹稍。
相信我貼上代碼大家一看就立刻明白了,非常簡單的東西部服。不過嘛唆姐,咱們還是想了解一下制作思路:

先分析餅狀圖的構(gòu)成,非常明顯廓八,餅狀圖就是一個又一個的扇形構(gòu)成的奉芦,每個扇形都有不同的顏色,對應(yīng)的有名字剧蹂,數(shù)據(jù)和百分比声功。

經(jīng)以上信息可以得出餅狀圖的最基本數(shù)據(jù)應(yīng)包括:名字 數(shù)據(jù)值 百分比 對應(yīng)的角度 顏色

用戶關(guān)心的數(shù)據(jù) : 名字 數(shù)據(jù)值 百分比

需要程序計算的數(shù)據(jù): 百分比 對應(yīng)的角度

其中顏色這一項可以用戶指定也可以用程序指定(我們這里采用程序指定)宠叼。

封裝數(shù)據(jù):

public class PieData {
    // 用戶關(guān)心數(shù)據(jù)
    private String name;        // 名字
    private float value;        // 數(shù)值
    private float percentage;   // 百分比
    
    // 非用戶關(guān)心數(shù)據(jù)
    private int color = 0;      // 顏色
    private float angle = 0;    // 角度

    public PieData(@NonNull String name, @NonNull float value) {
        this.name = name;
        this.value = value;
    }
}

PS: 以上省略了get set方法

自定義View:

先按照自定義View流程梳理一遍(確定各個步驟應(yīng)該做的事情):

步驟 關(guān)鍵字 作用
1 構(gòu)造函數(shù) 初始化(初始化畫筆Paint)
2 onMeasure 測量View的大小(暫時不用關(guān)心)
3 onSizeChanged 確定View大小(記錄當(dāng)前View的寬高)
4 onLayout 確定子View布局(無子View先巴,不關(guān)心)
5 onDraw 實際繪制內(nèi)容(繪制餅狀圖)
6 提供接口 提供接口(提供設(shè)置數(shù)據(jù)的接口)

代碼如下:

public class PieView extends View {
    // 顏色表 (注意: 此處定義顏色使用的是ARGB,帶Alpha通道的)
    private int[] mColors = {0xFFCCFF00, 0xFF6495ED, 0xFFE32636, 0xFF800000, 0xFF808000, 0xFFFF8C69, 0xFF808080,
            0xFFE6B800, 0xFF7CFC00};
    // 餅狀圖初始繪制角度
    private float mStartAngle = 0;
    // 數(shù)據(jù)
    private ArrayList<PieData> mData;
    // 寬高
    private int mWidth, mHeight;
    // 畫筆
    private Paint mPaint = new Paint();

    public PieView(Context context) {
        this(context, null);
    }

    public PieView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (null == mData)
            return;
        float currentStartAngle = mStartAngle;                    // 當(dāng)前起始角度
        canvas.translate(mWidth / 2, mHeight / 2);                // 將畫布坐標(biāo)原點移動到中心位置
        float r = (float) (Math.min(mWidth, mHeight) / 2 * 0.8);  // 餅狀圖半徑
        RectF rect = new RectF(-r, -r, r, r);                     // 餅狀圖繪制區(qū)域

        for (int i = 0; i < mData.size(); i++) {
            PieData pie = mData.get(i);
            mPaint.setColor(pie.getColor());
            canvas.drawArc(rect, currentStartAngle, pie.getAngle(), true, mPaint);
            currentStartAngle += pie.getAngle();
        }

    }

    // 設(shè)置起始角度
    public void setStartAngle(int mStartAngle) {
        this.mStartAngle = mStartAngle;
        invalidate();   // 刷新
    }

    // 設(shè)置數(shù)據(jù)
    public void setData(ArrayList<PieData> mData) {
        this.mData = mData;
        initDate(mData);
        invalidate();   // 刷新
    }

    // 初始化數(shù)據(jù)
    private void initDate(ArrayList<PieData> mData) {
        if (null == mData || mData.size() == 0)   // 數(shù)據(jù)有問題 直接返回
            return;

        float sumValue = 0;
        for (int i = 0; i < mData.size(); i++) {
            PieData pie = mData.get(i);

            sumValue += pie.getValue();       //計算數(shù)值和

            int j = i % mColors.length;       //設(shè)置顏色
            pie.setColor(mColors[j]);
        }

        float sumAngle = 0;
        for (int i = 0; i < mData.size(); i++) {
            PieData pie = mData.get(i);

            float percentage = pie.getValue() / sumValue;   // 百分比
            float angle = percentage * 360;                 // 對應(yīng)的角度

            pie.setPercentage(percentage);                  // 記錄百分比
            pie.setAngle(angle);                            // 記錄角度大小
            sumAngle += angle;

            Log.i("angle", "" + pie.getAngle());
        }
    }
}

PS: 在更改了數(shù)據(jù)需要重繪界面時要調(diào)用invalidate()這個函數(shù)重新繪制车吹。

效果圖

PS: 這個餅狀圖并沒有添加百分比等數(shù)據(jù)筹裕,僅作為示例使用。

PieView源碼下載

總結(jié):

其實自定義View只要按照流程一步步的走窄驹,也是比較容易的朝卒。不過里面也有不少坑,這些坑還是自己踩過印象比較深乐埠,建議大家不要直接copy源碼抗斤,自己手打體驗一下。

About

本系列相關(guān)文章

作者微博: GcsSloop

參考資料:

View

Canvas

Android Canvas繪圖詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末丈咐,一起剝皮案震驚了整個濱河市瑞眼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌棵逊,老刑警劉巖伤疙,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡徒像,警方通過查閱死者的電腦和手機(jī)黍特,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锯蛀,“玉大人灭衷,你說我怎么就攤上這事∨缘樱” “怎么了翔曲?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長劈愚。 經(jīng)常有香客問我瞳遍,道長,這世上最難降的妖魔是什么造虎? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任傅蹂,我火速辦了婚禮,結(jié)果婚禮上算凿,老公的妹妹穿的比我還像新娘份蝴。我一直安慰自己,他們只是感情好氓轰,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布婚夫。 她就那樣靜靜地躺著,像睡著了一般署鸡。 火紅的嫁衣襯著肌膚如雪案糙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天靴庆,我揣著相機(jī)與錄音时捌,去河邊找鬼。 笑死炉抒,一個胖子當(dāng)著我的面吹牛奢讨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播焰薄,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拿诸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了塞茅?” 一聲冷哼從身側(cè)響起亩码,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎野瘦,沒想到半個月后描沟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年啊掏,在試婚紗的時候發(fā)現(xiàn)自己被綠了蠢络。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡迟蜜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啡省,到底是詐尸還是另有隱情娜睛,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布卦睹,位于F島的核電站畦戒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏结序。R本人自食惡果不足惜障斋,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望徐鹤。 院中可真熱鬧垃环,春花似錦、人聲如沸返敬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劲赠。三九已至涛目,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凛澎,已是汗流浹背霹肝。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留塑煎,地道東北人沫换。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像轧叽,于是被迫代替她去往敵國和親苗沧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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