Android自定義View-蜘蛛網(wǎng)屬性圖(五邊形圖)

首先看看效果圖:

這里寫圖片描述
這里寫圖片描述

先簡要說一下這里需要涉及到的知識點(diǎn):

  1. 2D繪圖基礎(chǔ)博烂。
  2. 高中基本的三角函數(shù) Sin畜伐,Cos。

參考的文章:

  1. Android自定義控件 芝麻信用分雷達(dá)圖

這里為了尊重上面這篇文章的作者遇西,需要說明一下,下面的代碼有部分是參考上面這篇文章的严嗜。這里我學(xué)習(xí)之后有了自己的理解粱檀。做了一點(diǎn)小改動,然后以自己的思路來捋一捋漫玄。希望我的文字對你更有幫助茄蚯,哈哈。 (Pentagon --五邊形)

繪制思路:

  1. 計算三個五邊形的五個頂點(diǎn)的坐標(biāo)睦优,用 path 連接起來并繪制
  2. 計算要顯示的數(shù)據(jù)的五個頂點(diǎn)的坐標(biāo)渗常,用 path 連接起來并繪制
  3. 繪制五條射線
  4. 計算圖標(biāo)和標(biāo)題的坐標(biāo)位置,并繪制
  5. 繪制中間的分?jǐn)?shù)

第一步:繪制三個五邊形和紅色五邊形

這里寫圖片描述

初始化成員變量

private int dataCount = 5;//多邊形維度
private float radian = (float) (Math.PI * 2 / dataCount);//每個維度的角度
private float radius;//一條星射線的長度汗盘,即是發(fā)散的五條線白線
private int centerX;//中心坐標(biāo) Y
private int centerY;//中心坐標(biāo) X
private String[] titles = {"履約能力", "信用歷史", "人脈關(guān)系", "行為偏好", "身份特質(zhì)"};//標(biāo)題
private int[] icos = {R.mipmap.ic_launcher, R.mipmap.ic_launcher, R.mipmap.ic_launcher, R.mipmap.ic_launcher, R.mipmap.ic_launcher};//五個維度的圖標(biāo)
private float[] data = {170, 180, 100, 170, 150};//五個維度的數(shù)據(jù)值
private float maxValue = 190;//每個維度的最大值
private Paint mPaintText;//繪制文字的畫筆
private int radarMargin = 40;//
private int mAlpha;//白色五邊形的透明度
private Path mPentagonPath;//記錄白色五邊形的路徑
private Paint mPentagonPaint;//繪制白色五邊形的畫筆
private Path mDataPath;//記錄紅色五邊形的路徑
private Paint mDataPaint;//繪制紅色五邊形的畫筆

構(gòu)造方法中初始化的數(shù)據(jù)

private void init() {
    mPentagonPaint = new Paint();//初始化白色五邊形的畫筆
    mPentagonPaint.setAntiAlias(true);//
    mPentagonPaint.setStrokeWidth(5);//
    mPentagonPaint.setColor(Color.WHITE);//
    mPentagonPaint.setStyle(Paint.Style.FILL_AND_STROKE);//

    mDataPaint = new Paint();//初始化紅色五邊形的畫筆
    mDataPaint.setAntiAlias(true);//
    mDataPaint.setStrokeWidth(10);//
    mDataPaint.setColor(Color.RED);//
    mDataPaint.setAlpha(150);//
    mDataPaint.setStyle(Paint.Style.STROKE);//

    mPaintText = new Paint();//初始化文字畫筆
    mPaintText.setAntiAlias(true);//
    mPaintText.setTextSize(50);//
    mPaintText.setColor(Color.WHITE);//
    mPaintText.setStyle(Paint.Style.FILL);//

    mPentagonPath = new Path();//初始化白色五邊形路徑
    mDataPath = new Path();//初始化紅色五邊形路徑
    radius = 80;//星射線的初始值凳谦,也是最小的五邊形的一條星射線的長度(后期會遞增)
    mAlpha = 150;//白色五邊形的透明度(后期后遞減)
}

初始化數(shù)據(jù)之后是通過 radius 的長度來計算五邊形五個頂點(diǎn)的坐標(biāo)值,后期通過改變 radius 的值衡未,來達(dá)到計算三個白色五邊形的五個頂點(diǎn)的值尸执。這里給出一張圖,幫助理解缓醋。通過圖中的兩個紅色三角形就可以求出頂點(diǎn)的坐標(biāo)了如失。

這里寫圖片描述

**右上角的頂點(diǎn)為第一個點(diǎn),順時針計算送粱,position 依次是 0褪贵,1,2抗俄,3脆丁,4 **

public Point getPoint(int position) {
    return getPoint(position, 0, 1);
}

// 參數(shù):position:頂點(diǎn)的位置,radarMargin:邊距动雹,percent:星射線長度的百分比槽卫,用于計算紅色五邊形的頂點(diǎn)
public Point getPoint(int position, int radarMargin, float percent) {//以五邊形的中心點(diǎn)為坐標(biāo)原點(diǎn)
    int x = 0;
    int y = 0;
    switch (position) {
        case 0://第一象限,右上角頂點(diǎn)的坐標(biāo)計算
            x = (int) (centerX + (radius + radarMargin) * Math.sin(radian) * percent);
            y = (int) (centerY - (radius + radarMargin) * Math.cos(radian) * percent);
            break;
        case 1://第四象限胰蝠,右下角頂點(diǎn)的坐標(biāo)計算
            x = (int) (centerX + (radius + radarMargin) * Math.sin(radian / 2) * percent);
            y = (int) (centerY + (radius + radarMargin) * Math.cos(radian / 2) * percent);
            break;
        case 2://第三象限歼培,左下角頂點(diǎn)的坐標(biāo)計算
            x = (int) (centerX - (radius + radarMargin) * Math.sin(radian / 2) * percent);
            y = (int) (centerY + (radius + radarMargin) * Math.cos(radian / 2) * percent);
            break;
        case 3://第二象限,左上角頂點(diǎn)的坐標(biāo)計算
            x = (int) (centerX - (radius + radarMargin) * Math.sin(radian) * percent);
            y = (int) (centerY - (radius + radarMargin) * Math.cos(radian) * percent);
            break;
        case 4:// Y 軸正方向頂點(diǎn)的計算
            x = centerX;
            y = (int) (centerY - (radius + radarMargin) * percent);
            break;
    }
    return new Point(x, y);
}

基礎(chǔ)工作都做足了茸塞,那么就進(jìn)行五邊形的繪制了

private void drawPentagon(Canvas canvas) {
    for (int j = 0; j < 3; j++) {//繪制三層白色五邊形
        radius += 70;//每一層五邊形的星射線增加 70 的長度
        mAlpha -= 30;//每一層五邊形的透明度減少 30
        mPentagonPaint.setAlpha(mAlpha);
        for (int i = 0; i < dataCount; i++) {//繪制一層
            if (i == 0) {
                mPentagonPath.moveTo(getPoint(i).x, getPoint(i).y);
            } else {
                mPentagonPath.lineTo(getPoint(i).x, getPoint(i).y);
            }
        }
        mPentagonPath.close();
        canvas.drawPath(mPentagonPath, mPentagonPaint);
    }

    for (int i = 0; i < dataCount; i++) {//繪制紅色五邊形
        float percent = data[i] / maxValue;//數(shù)據(jù)值與最大值的百分比
        if (i == 0) {
            mDataPath.moveTo(getPoint(i, 0, percent).x, getPoint(i, 0, percent).y);//通過百分比計算出紅色頂點(diǎn)的位置
        } else {
            mDataPath.lineTo(getPoint(i, 0, percent).x, getPoint(i, 0, percent).y);
        }
    }
    mDataPath.close();
    canvas.drawPath(mDataPath, mDataPaint);
}

第二步:繪制五條星射線

先來看看這一步的效果圖:

這里寫圖片描述

繪制好五邊形之后 radius 的值已經(jīng)為最大五邊形的星射線的長度了躲庄。

private void drawFiveLine(Canvas canvas) {
    mPentagonPaint.setColor(Color.WHITE);//設(shè)置顏色為白色
    mPentagonPaint.setStrokeWidth(2);//設(shè)置寬度為2
    for (int i = 0; i < dataCount; i++) {
        canvas.drawLine(centerX, centerY, getPoint(i).x, getPoint(i).y, mPentagonPaint);//繪制
    }
}

第三步:繪制五個標(biāo)題

先來看看這一步的效果圖:

這里寫圖片描述

在這一步,相對難一點(diǎn)的就是坐標(biāo)的計算了钾虐。第一個頂點(diǎn)的坐標(biāo)經(jīng)過添加 radarMargin 值之后就可以直接使用了噪窘,其他頂點(diǎn)還需要經(jīng)過計算得到。這里其實(shí)就是要計算每一個 Title 文字左下角的坐標(biāo)效扫。那么計算坐標(biāo)的代碼是這樣的:

private void drawTitle(Canvas canvas) {
    for (int i = 0; i < dataCount; i++) {
        int x = getPoint(i, radarMargin, 1).x;//獲取添加 radarMargin 值之后的 X 坐標(biāo)的指
        int y = getPoint(i, radarMargin, 1).y;//獲取添加 radarMargin 值之后的 Y 坐標(biāo)的指
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), icos[i]);
        int iconHeight = bitmap.getHeight();
        int titleWidth = (int) mPaintText.measureText(titles[i]);
        switch (i) {
            case 1://說明一下為什么是 iconHeight / 2 倔监,主要是因?yàn)檫@樣會比較好看
                y += iconHeight / 2;
                break;
            case 2:
                x -= titleWidth;
                y += iconHeight / 2;
                break;
            case 3:
                x -= titleWidth;
                break;
            case 4:
                x -= titleWidth / 2;
                break;
        }
        canvas.drawText(titles[i], x, y, mPaintText);
    }
}

第四步:繪制圖標(biāo)

先來看看這一步的效果:

這里寫圖片描述

這一步也是要進(jìn)行坐標(biāo)的計算直砂,主要的計算出放置圖標(biāo)左上角的坐標(biāo)值。這里還是相對簡單一點(diǎn)丐枉,不需要用到三角函數(shù)哆键。

private void drawIcon(Canvas canvas) {
    for (int i = 0; i < dataCount; i++) {
        int x = getPoint(i, radarMargin, 1).x;//獲取添加 radarMargin 值之后的 X 坐標(biāo)的指
        int y = getPoint(i, radarMargin, 1).y;//獲取添加 radarMargin 值之后的 Y 坐標(biāo)的指
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), icos[i]);
        int iconHeight = bitmap.getHeight();
        int iconWidth = bitmap.getWidth();
        int titleWidth = (int) mPaintText.measureText(titles[i]);
        switch (i) {
            case 0:
                x += (titleWidth - iconWidth) / 2;
                y -= (iconHeight + getTextHeight(titles[i]));
                break;
            case 1:
                x += (titleWidth - iconWidth) / 2;
                y -= (iconHeight / 2 + getTextHeight(titles[i]));
                break;
            case 2:
                x -= titleWidth - (titleWidth - iconWidth) / 2;
                y -= (iconHeight / 2 + getTextHeight(titles[i]));
                break;
            case 3:
                x -= titleWidth - (titleWidth - iconWidth) / 2;
                y -= (iconHeight + getTextHeight(titles[i]));
                break;
            case 4:
                x -= (iconHeight / 2);
                y -= (iconHeight + getTextHeight(titles[i]));
                break;
        }
        canvas.drawBitmap(bitmap, x, y, mPaintText);
    }
}

第五步:繪制中心點(diǎn)的分?jǐn)?shù)

這一步完成之后就可以得到最終效果了瘦锹,就是圖一的效果:

這里寫圖片描述
這里寫圖片描述

文字的坐標(biāo)是中心點(diǎn),那么計算出文字的寬度和高度就可以居中顯示文字了。

private void drawScore(Canvas canvas) {
    mPaintText.setColor(getResources().getColor(R.color.colorAccent));
    int score = 0;
    for (int i = 0; i < data.length; i++) {//累加分?jǐn)?shù)值
        score += data[i];
    }
    String str_score = String.valueOf(score);
    Paint.FontMetrics fm = mPaintText.getFontMetrics();//用于計算文字的高度
    canvas.drawText(str_score, centerX - mPaintText.measureText(str_score) / 2, (centerY + (int) Math.ceil(fm.descent - fm.ascent) / 2), mPaintText);
}

總結(jié)

一步步下來,對自定義 view 也有了進(jìn)一步的了解头岔。感覺需要更多的練習(xí)才能完全 hold 住。如果文中有什么知識點(diǎn)是錯誤的或者更好的實(shí)現(xiàn)方法类浪,請及時聯(lián)系我進(jìn)行修改,以免誤導(dǎo)別人肌似。謝謝费就。那么完整的代碼是這樣的。

/**
 * Created by zone on 2017/4/9.
 */

public class PentagonView extends View {
    private int dataCount = 5;//多邊形維度锈嫩,這里是五邊形
    private float radian = (float) (Math.PI * 2 / dataCount);//每個維度的角度
    private float radius;//一條星射線的長度受楼,即是發(fā)散的五條線白線
    private int centerX;//中心坐標(biāo) Y
    private int centerY;//中心坐標(biāo) X
    private String[] titles = {"履約能力", "信用歷史", "人脈關(guān)系", "行為偏好", "身份特質(zhì)"};//標(biāo)題
    private int[] icos = {R.mipmap.ic_launcher, R.mipmap.ic_launcher, R.mipmap.ic_launcher, R.mipmap.ic_launcher, R.mipmap.ic_launcher};//五個維度的圖標(biāo)
    private float[] data = {170, 180, 100, 170, 150};//五個維度的數(shù)據(jù)值
    private float maxValue = 190;//每個維度的最大值
    private Paint mPaintText;//繪制文字的畫筆
    private int radarMargin = 40;//
    private int mAlpha;//白色五邊形的透明度
    private Path mPentagonPath;//記錄白色五邊形的路徑
    private Paint mPentagonPaint;//繪制白色五邊形的畫筆
    private Path mDataPath;//記錄紅色五邊形的路徑
    private Paint mDataPaint;//繪制紅色五邊形的畫筆


    public PentagonView(Context context) {
        super(context);
        init();
    }

    public PentagonView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PentagonView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public PentagonView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        mPentagonPaint = new Paint();//初始化白色五邊形的畫筆
        mPentagonPaint.setAntiAlias(true);//
        mPentagonPaint.setStrokeWidth(5);//
        mPentagonPaint.setColor(Color.WHITE);//
        mPentagonPaint.setStyle(Paint.Style.FILL_AND_STROKE);//

        mDataPaint = new Paint();//初始化紅色五邊形的畫筆
        mDataPaint.setAntiAlias(true);//
        mDataPaint.setStrokeWidth(10);//
        mDataPaint.setColor(Color.RED);//
        mDataPaint.setAlpha(150);//
        mDataPaint.setStyle(Paint.Style.STROKE);//

        mPaintText = new Paint();//初始化文字畫筆
        mPaintText.setAntiAlias(true);//
        mPaintText.setTextSize(50);//
        mPaintText.setColor(Color.WHITE);//
        mPaintText.setStyle(Paint.Style.FILL);//

        mPentagonPath = new Path();//初始化白色五邊形路徑
        mDataPath = new Path();//初始化紅色五邊形路徑
        radius = 80;//星射線的初始值,也是最小的五邊形的一條星射線的長度(后期會遞增)
        mAlpha = 150;//白色五邊形的透明度(后期后遞減)
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(getResources().getColor(R.color.colorAccent));
        centerX = getWidth() / 2;
        centerY = getHeight() / 2;
        drawPentagon(canvas);//繪制白色五邊形和紅色五邊形
        drawFiveLine(canvas);//繪制五條星射線
        drawTitle(canvas);//繪制五個標(biāo)題
        drawIcon(canvas);//繪制五個圖標(biāo)
        drawScore(canvas);//繪制中間的分?jǐn)?shù)
    }

    private void drawPentagon(Canvas canvas) {
        for (int j = 0; j < 3; j++) {//繪制三層白色五邊形
            radius += 70;//每一層五邊形的星射線增加 70 的長度
            mAlpha -= 30;//每一層五邊形的透明度減少 30
            mPentagonPaint.setAlpha(mAlpha);
            for (int i = 0; i < dataCount; i++) {//繪制一層
                if (i == 0) {
                    mPentagonPath.moveTo(getPoint(i).x, getPoint(i).y);
                } else {
                    mPentagonPath.lineTo(getPoint(i).x, getPoint(i).y);
                }
            }
            mPentagonPath.close();
            canvas.drawPath(mPentagonPath, mPentagonPaint);
        }

        for (int i = 0; i < dataCount; i++) {//繪制紅色五邊形
            float percent = data[i] / maxValue;//數(shù)據(jù)值與最大值的百分比
            if (i == 0) {
                mDataPath.moveTo(getPoint(i, 0, percent).x, getPoint(i, 0, percent).y);//通過百分比計算出紅色頂點(diǎn)的位置
            } else {
                mDataPath.lineTo(getPoint(i, 0, percent).x, getPoint(i, 0, percent).y);
            }
        }
        mDataPath.close();
        canvas.drawPath(mDataPath, mDataPaint);
    }

    private void drawFiveLine(Canvas canvas) {
        mPentagonPaint.setColor(Color.WHITE);//設(shè)置顏色為白色
        mPentagonPaint.setStrokeWidth(2);//設(shè)置寬度為2
        for (int i = 0; i < dataCount; i++) {
            canvas.drawLine(centerX, centerY, getPoint(i).x, getPoint(i).y, mPentagonPaint);//繪制
        }
    }

    private void drawIcon(Canvas canvas) {
        for (int i = 0; i < dataCount; i++) {
            int x = getPoint(i, radarMargin, 1).x;//獲取添加 radarMargin 值之后的 X 坐標(biāo)的指
            int y = getPoint(i, radarMargin, 1).y;//獲取添加 radarMargin 值之后的 Y 坐標(biāo)的指
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), icos[i]);
            int iconHeight = bitmap.getHeight();
            int iconWidth = bitmap.getWidth();
            int titleWidth = (int) mPaintText.measureText(titles[i]);
            switch (i) {
                case 0:
                    x += (titleWidth - iconWidth) / 2;
                    y -= (iconHeight + getTextHeight(titles[i]));
                    break;
                case 1:
                    x += (titleWidth - iconWidth) / 2;
                    y -= (iconHeight / 2 + getTextHeight(titles[i]));
                    break;
                case 2:
                    x -= titleWidth - (titleWidth - iconWidth) / 2;
                    y -= (iconHeight / 2 + getTextHeight(titles[i]));
                    break;
                case 3:
                    x -= titleWidth - (titleWidth - iconWidth) / 2;
                    y -= (iconHeight + getTextHeight(titles[i]));
                    break;
                case 4:
                    x -= (iconHeight / 2);
                    y -= (iconHeight + getTextHeight(titles[i]));
                    break;
            }
            canvas.drawBitmap(bitmap, x, y, mPaintText);
        }
    }

    private int getTextHeight(String text) {
        Paint.FontMetrics fm = mPaintText.getFontMetrics();
        return (int) Math.ceil(fm.descent - fm.ascent);
    }

    private void drawTitle(Canvas canvas) {
        for (int i = 0; i < dataCount; i++) {
            int x = getPoint(i, radarMargin, 1).x;//獲取添加 radarMargin 值之后的 X 坐標(biāo)的指
            int y = getPoint(i, radarMargin, 1).y;//獲取添加 radarMargin 值之后的 Y 坐標(biāo)的指
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), icos[i]);
            int iconHeight = bitmap.getHeight();
            int titleWidth = (int) mPaintText.measureText(titles[i]);
            switch (i) {
                case 1://說明一下為什么是 iconHeight / 2 呼寸,主要是因?yàn)檫@樣會比較好看
                    y += iconHeight / 2;
                    break;
                case 2:
                    x -= titleWidth;
                    y += iconHeight / 2;
                    break;
                case 3:
                    x -= titleWidth;
                    break;
                case 4:
                    x -= titleWidth / 2;
                    break;
            }
            canvas.drawText(titles[i], x, y, mPaintText);
        }
    }

    private void drawScore(Canvas canvas) {
        mPaintText.setColor(getResources().getColor(R.color.colorAccent));
        int score = 0;
        for (int i = 0; i < data.length; i++) {//累加分?jǐn)?shù)值
            score += data[i];
        }
        String str_score = String.valueOf(score);
        Paint.FontMetrics fm = mPaintText.getFontMetrics();//用于計算文字的高度
        canvas.drawText(str_score, centerX - mPaintText.measureText(str_score) / 2, (centerY + (int) Math.ceil(fm.descent - fm.ascent) / 2), mPaintText);
    }

    public Point getPoint(int position) {
        return getPoint(position, 0, 1);
    }

// 右上角的頂點(diǎn)為第一個點(diǎn),順時針計算猴贰,position 依次是 0对雪,1,2米绕,3瑟捣,4
// 參數(shù):position:頂點(diǎn)的位置馋艺,radarMargin:邊距,percent:星射線長度的百分比迈套,用于計算紅色五邊形的頂點(diǎn)
    public Point getPoint(int position, int radarMargin, float percent) {//以五邊形的中心點(diǎn)為坐標(biāo)原點(diǎn)
        int x = 0;
        int y = 0;
        switch (position) {
            case 0://第一象限捐祠,右上角頂點(diǎn)的坐標(biāo)計算
                x = (int) (centerX + (radius + radarMargin) * Math.sin(radian) * percent);
                y = (int) (centerY - (radius + radarMargin) * Math.cos(radian) * percent);
                break;
            case 1://第四象限,右下角頂點(diǎn)的坐標(biāo)計算
                x = (int) (centerX + (radius + radarMargin) * Math.sin(radian / 2) * percent);
                y = (int) (centerY + (radius + radarMargin) * Math.cos(radian / 2) * percent);
                break;
            case 2://第三象限桑李,左下角頂點(diǎn)的坐標(biāo)計算
                x = (int) (centerX - (radius + radarMargin) * Math.sin(radian / 2) * percent);
                y = (int) (centerY + (radius + radarMargin) * Math.cos(radian / 2) * percent);
                break;
            case 3://第二象限踱蛀,左上角頂點(diǎn)的坐標(biāo)計算
                x = (int) (centerX - (radius + radarMargin) * Math.sin(radian) * percent);
                y = (int) (centerY - (radius + radarMargin) * Math.cos(radian) * percent);
                break;
            case 4:// Y 軸正方向頂點(diǎn)的計算
                x = centerX;
                y = (int) (centerY - (radius + radarMargin) * percent);
                break;
        }
        return new Point(x, y);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市贵白,隨后出現(xiàn)的幾起案子率拒,更是在濱河造成了極大的恐慌,老刑警劉巖禁荒,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猬膨,死亡現(xiàn)場離奇詭異,居然都是意外死亡呛伴,警方通過查閱死者的電腦和手機(jī)勃痴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來热康,“玉大人沛申,你說我怎么就攤上這事『致。” “怎么了污它?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長庶弃。 經(jīng)常有香客問我衫贬,道長,這世上最難降的妖魔是什么歇攻? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任固惯,我火速辦了婚禮,結(jié)果婚禮上缴守,老公的妹妹穿的比我還像新娘葬毫。我一直安慰自己,他們只是感情好屡穗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布贴捡。 她就那樣靜靜地躺著,像睡著了一般村砂。 火紅的嫁衣襯著肌膚如雪烂斋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音汛骂,去河邊找鬼罕模。 笑死,一個胖子當(dāng)著我的面吹牛帘瞭,可吹牛的內(nèi)容都是我干的淑掌。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼蝶念,長吁一口氣:“原來是場噩夢啊……” “哼抛腕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起祸轮,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤兽埃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后适袜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柄错,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年苦酱,在試婚紗的時候發(fā)現(xiàn)自己被綠了售貌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡疫萤,死狀恐怖颂跨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扯饶,我是刑警寧澤恒削,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站尾序,受9級特大地震影響钓丰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜每币,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一携丁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧兰怠,春花似錦梦鉴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秸侣,卻和暖如春快骗,著一層夾襖步出監(jiān)牢的瞬間娜庇,已是汗流浹背塔次。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工方篮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人励负。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓藕溅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親继榆。 傳聞我的和親對象是個殘疾皇子巾表,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

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