Android自定義View——從零開始實(shí)現(xiàn)雪花飄落效果

版權(quán)聲明:本文為博主原創(chuàng)文章赖欣,未經(jīng)博主允許不得轉(zhuǎn)載。
系列教程:Android開發(fā)之從零開始系列
源碼:github.com/AnliaLee/FallingView毁嗦,歡迎star

大家要是看到有錯(cuò)誤的地方或者有啥好的建議卵蛉,歡迎留言評(píng)論

前言:轉(zhuǎn)眼已是十一月下旬了瓜挽,天氣慢慢轉(zhuǎn)冷盹廷,不知道北方是不是已經(jīng)開始下雪了呢?本期教程我們就順應(yīng)季節(jié)主題久橙,一起來實(shí)現(xiàn) 雪花飄落的效果吧俄占。本篇效果思路參考自國外大神的Android實(shí)現(xiàn)雪花飛舞效果,并在此基礎(chǔ)上實(shí)現(xiàn)進(jìn)一步的封裝和功能擴(kuò)展

本篇只著重于思路和實(shí)現(xiàn)步驟淆衷,里面用到的一些知識(shí)原理不會(huì)非常細(xì)地拿來講缸榄,如果有不清楚的api或方法可以在網(wǎng)上搜下相應(yīng)的資料,肯定有大神講得非常清楚的祝拯,我這就不獻(xiàn)丑了甚带。本著認(rèn)真負(fù)責(zé)的精神我會(huì)把相關(guān)知識(shí)的博文鏈接也貼出來(其實(shí)就是懶不想寫那么多哈哈),大家可以自行傳送佳头。為了照顧第一次閱讀系列博客的小伙伴鹰贵,本篇會(huì)出現(xiàn)一些在之前系列博客就講過的內(nèi)容,看過的童鞋自行跳過該段即可

國際慣例畜晰,先上效果圖

目錄
  • 繪制一個(gè)循環(huán)下落的“雪球”
  • 封裝下落物體對(duì)象
  • 擴(kuò)展一:增加導(dǎo)入Drawable資源的構(gòu)造方法和設(shè)置物體大小的接口
  • 擴(kuò)展一:擴(kuò)展二:實(shí)現(xiàn)雪花“大小不一”砾莱、“快慢有別”的效果
  • 擴(kuò)展三:引入“風(fēng)”的概念

繪制一個(gè)循環(huán)下落的“雪球”

我們先從最簡單的部分做起瑞筐,自定義View中實(shí)現(xiàn)循環(huán)動(dòng)畫的方法有很多凄鼻,最簡單直接的當(dāng)然是用Animation類去實(shí)現(xiàn),但考慮到無論是雪花聚假、雪球亦或是雨滴什么的块蚌,每個(gè)獨(dú)立的個(gè)體都有自己的起點(diǎn)、速度和方向等等膘格,其下落的過程會(huì)出現(xiàn)很多隨機(jī)的因素峭范,實(shí)現(xiàn)這種非規(guī)律的動(dòng)畫Animation類就不怎么適用了,因此我們這次要利用線程通信實(shí)現(xiàn)一個(gè)簡單的定時(shí)器瘪贱,達(dá)到周期性繪制View的效果纱控。這里我們簡單繪制一個(gè)“雪球”(其實(shí)就是個(gè)白色背景的圓形哈哈)來看看定時(shí)器的效果辆毡,新建一個(gè)FallingView

public class FallingView extends View {

    private Context mContext;
    private AttributeSet mAttrs;

    private int viewWidth;
    private int viewHeight;

    private static final int defaultWidth = 600;//默認(rèn)寬度
    private static final int defaultHeight = 1000;//默認(rèn)高度
    private static final int intervalTime = 5;//重繪間隔時(shí)間

    private Paint testPaint;
    private int snowY;

    public FallingView(Context context) {
        super(context);
        mContext = context;
        init();
    }

    public FallingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mAttrs = attrs;
        init();
    }

    private void init(){
        testPaint = new Paint();
        testPaint.setColor(Color.WHITE);
        testPaint.setStyle(Paint.Style.FILL);
        snowY = 0;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = measureSize(defaultHeight, heightMeasureSpec);
        int width = measureSize(defaultWidth, widthMeasureSpec);
        setMeasuredDimension(width, height);

        viewWidth = width;
        viewHeight = height;
    }

    private int measureSize(int defaultSize,int measureSpec) {
        int result = defaultSize;
        int specMode = View.MeasureSpec.getMode(measureSpec);
        int specSize = View.MeasureSpec.getSize(measureSpec);

        if (specMode == View.MeasureSpec.EXACTLY) {
            result = specSize;
        } else if (specMode == View.MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
        return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(100,snowY,25,testPaint);
        getHandler().postDelayed(runnable, intervalTime);//間隔一段時(shí)間再進(jìn)行重繪
    }

    // 重繪線程
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            snowY += 15;
            if(snowY>viewHeight){//超出屏幕則重置雪球位置
                snowY = 0;
            }
            invalidate();
        }
    };
}

效果如圖

在上述代碼中View基本的框架我們已經(jīng)搭好了,思路其實(shí)很簡單甜害,我們需要做僅僅是在每次重繪之前更新做下落運(yùn)動(dòng)的物體的位置即可

封裝下落物體對(duì)象

相關(guān)博文鏈接

Android開發(fā)中無處不在的設(shè)計(jì)模式——Builder模式
[Android] 獲取View的寬度和高度

要實(shí)現(xiàn)大雪紛飛的效果舶掖,很明顯只有一個(gè)雪球是不夠的,而且雪也不能只有雪球一個(gè)形狀尔店,我們希望可以自定義雪的樣式眨攘,甚至不局限于下雪,還可以下雨嚣州、下金幣等等鲫售,因此我們要對(duì)下落的物體進(jìn)行封裝。為了以后物體類對(duì)外方法代碼的可讀性该肴,這里我們采用Builder設(shè)計(jì)模式來構(gòu)建物體對(duì)象類情竹,新建FallObject

public class FallObject {
    private int initX;
    private int initY;
    private Random random;
    private int parentWidth;//父容器寬度
    private int parentHeight;//父容器高度
    private float objectWidth;//下落物體寬度
    private float objectHeight;//下落物體高度

    public int initSpeed;//初始下降速度

    public float presentX;//當(dāng)前位置X坐標(biāo)
    public float presentY;//當(dāng)前位置Y坐標(biāo)
    public float presentSpeed;//當(dāng)前下降速度

    private Bitmap bitmap;
    public Builder builder;

    private static final int defaultSpeed = 10;//默認(rèn)下降速度

    public FallObject(Builder builder, int parentWidth, int parentHeight){
        random = new Random();
        this.parentWidth = parentWidth;
        this.parentHeight = parentHeight;
        initX = random.nextInt(parentWidth);//隨機(jī)物體的X坐標(biāo)
        initY = random.nextInt(parentHeight)- parentHeight;//隨機(jī)物體的Y坐標(biāo),并讓物體一開始從屏幕頂部下落
        presentX = initX;
        presentY = initY;

        initSpeed = builder.initSpeed;

        presentSpeed = initSpeed;
        bitmap = builder.bitmap;
        objectWidth = bitmap.getWidth();
        objectHeight = bitmap.getHeight();
    }

    private FallObject(Builder builder) {
        this.builder = builder;
        initSpeed = builder.initSpeed;
        bitmap = builder.bitmap;
    }

    public static final class Builder {
        private int initSpeed;
        private Bitmap bitmap;

        public Builder(Bitmap bitmap) {
            this.initSpeed = defaultSpeed;
            this.bitmap = bitmap;
        }

        /**
         * 設(shè)置物體的初始下落速度
         * @param speed
         * @return
         */
        public Builder setSpeed(int speed) {
            this.initSpeed = speed;
            return this;
        }

        public FallObject build() {
            return new FallObject(this);
        }
    }

    /**
     * 繪制物體對(duì)象
     * @param canvas
     */
    public void drawObject(Canvas canvas){
        moveObject();
        canvas.drawBitmap(bitmap,presentX,presentY,null);
    }

    /**
     * 移動(dòng)物體對(duì)象
     */
    private void moveObject(){
        moveY();
        if(presentY>parentHeight){
            reset();
        }
    }

    /**
     * Y軸上的移動(dòng)邏輯
     */
    private void moveY(){
        presentY += presentSpeed;
    }

    /**
     * 重置object位置
     */
    private void reset(){
        presentY = -objectHeight;
        presentSpeed = initSpeed;
    }
}

FallingView中相應(yīng)地設(shè)置添加物體的方法

public class FallingView extends View {
    //省略部分代碼...
    private List<FallObject> fallObjects;

    private void init(){
        fallObjects = new ArrayList<>();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(fallObjects.size()>0){
            for (int i=0;i<fallObjects.size();i++) {
                //然后進(jìn)行繪制
                fallObjects.get(i).drawObject(canvas);
            }
            // 隔一段時(shí)間重繪一次, 動(dòng)畫效果
            getHandler().postDelayed(runnable, intervalTime);
        }
    }

    // 重繪線程
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            invalidate();
        }
    };

    /**
     * 向View添加下落物體對(duì)象
     * @param fallObject 下落物體對(duì)象
     * @param num
     */
    public void addFallObject(final FallObject fallObject, final int num) {
        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                getViewTreeObserver().removeOnPreDrawListener(this);
                for (int i = 0; i < num; i++) {
                    FallObject newFallObject = new FallObject(fallObject.builder,viewWidth,viewHeight);
                    fallObjects.add(newFallObject);
                }
                invalidate();
                return true;
            }
        });
    }
}

Activity中向FallingView添加一些物體看看效果

//繪制雪球bitmap
snowPaint = new Paint();
snowPaint.setColor(Color.WHITE);
snowPaint.setStyle(Paint.Style.FILL);
bitmap = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas(bitmap);
bitmapCanvas.drawCircle(25,25,25,snowPaint);

//初始化一個(gè)雪球樣式的fallObject
FallObject.Builder builder = new FallObject.Builder(bitmap);
FallObject fallObject = builder
        .setSpeed(10)
        .build();

fallingView = (FallingView) findViewById(R.id.fallingView);
fallingView.addFallObject(fallObject,50);//添加50個(gè)雪球?qū)ο?

效果如圖

到這里我們完成了一個(gè)最基礎(chǔ)的下落物體類匀哄,下面開始擴(kuò)展功能和效果


擴(kuò)展一:增加導(dǎo)入Drawable資源的構(gòu)造方法和設(shè)置物體大小的接口

我們之前的FallObject類中Builder只支持bitmap的導(dǎo)入鲤妥,很多時(shí)候我們的圖片樣式都是從drawable資源文件夾中獲取的,每次都要將drawable轉(zhuǎn)成bitmap是件很麻煩的事拱雏,因此我們要在FallObject類中封裝drawable資源導(dǎo)入的構(gòu)造方法棉安,修改FallObject

public static final class Builder {
    //省略部分代碼...
    public Builder(Bitmap bitmap) {
        this.initSpeed = defaultSpeed;
        this.bitmap = bitmap;
    }

    public Builder(Drawable drawable) {
        this.initSpeed = defaultSpeed;
        this.bitmap = drawableToBitmap(drawable);
    }
}

/**
 * drawable圖片資源轉(zhuǎn)bitmap
 * @param drawable
 * @return
 */
public static Bitmap drawableToBitmap(Drawable drawable) {
    Bitmap bitmap = Bitmap.createBitmap(
            drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight(),
            drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                    : Bitmap.Config.RGB_565);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    drawable.draw(canvas);
    return bitmap;
}

有了drawable資源導(dǎo)入的構(gòu)造方法,肯定需要配套改變FallObject圖片樣式大小的接口铸抑,依然是在FallObjectBuilder中擴(kuò)展相應(yīng)的接口

public static final class Builder {
    //省略部分代碼...
    public Builder setSize(int w, int h){
        this.bitmap = changeBitmapSize(this.bitmap,w,h);
        return this;
    }
}

/**
 * 改變bitmap的大小
 * @param bitmap 目標(biāo)bitmap
 * @param newW 目標(biāo)寬度
 * @param newH 目標(biāo)高度
 * @return
 */
public static Bitmap changeBitmapSize(Bitmap bitmap, int newW, int newH) {
    int oldW = bitmap.getWidth();
    int oldH = bitmap.getHeight();
    // 計(jì)算縮放比例
    float scaleWidth = ((float) newW) / oldW;
    float scaleHeight = ((float) newH) / oldH;
    // 取得想要縮放的matrix參數(shù)
    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleHeight);
    // 得到新的圖片
    bitmap = Bitmap.createBitmap(bitmap, 0, 0, oldW, oldH, matrix, true);
    return bitmap;
}

Activity中初始化下落物體樣式時(shí)我們就可以導(dǎo)入drawable資源和設(shè)置物體大小了(圖片資源我是在阿里圖標(biāo)庫下載的)

FallObject.Builder builder = new FallObject.Builder(getResources().getDrawable(R.drawable.ic_snow));
FallObject fallObject = builder
        .setSpeed(10)
        .setSize(50,50)
        .build();

來看下效果


擴(kuò)展二:實(shí)現(xiàn)雪花“大小不一”贡耽、“快慢有別”的效果

之前我們通過導(dǎo)入drawable資源的方法讓屏幕“下起了雪花”,但雪花個(gè)個(gè)都一樣大小鹊汛,下落速度也都完全一致蒲赂,這顯得十分的單調(diào),看起來一點(diǎn)也不像現(xiàn)實(shí)中的下雪場景刁憋。因此我們需要利用隨機(jī)數(shù)實(shí)現(xiàn)雪花“大小不一”滥嘴、“快慢有別”的效果,修改FallObject

public class FallObject {
    //省略部分代碼...
    private boolean isSpeedRandom;//物體初始下降速度比例是否隨機(jī)
    private boolean isSizeRandom;//物體初始大小比例是否隨機(jī)

    public FallObject(Builder builder, int parentWidth, int parentHeight){
        //省略部分代碼...
        this.builder = builder;
        isSpeedRandom = builder.isSpeedRandom;
        isSizeRandom = builder.isSizeRandom;

        initSpeed = builder.initSpeed;
        randomSpeed();
        randomSize();
    }

    private FallObject(Builder builder) {
        //省略部分代碼...
        isSpeedRandom = builder.isSpeedRandom;
        isSizeRandom = builder.isSizeRandom;
    }

    public static final class Builder {
        //省略部分代碼...
        private boolean isSpeedRandom;
        private boolean isSizeRandom;

        public Builder(Bitmap bitmap) {
            //省略部分代碼...
            this.isSpeedRandom = false;
            this.isSizeRandom = false;
        }

        public Builder(Drawable drawable) {
            //省略部分代碼...
            this.isSpeedRandom = false;
            this.isSizeRandom = false;
        }

        /**
         * 設(shè)置物體的初始下落速度
         * @param speed
         * @return
         */
        public Builder setSpeed(int speed) {
            this.initSpeed = speed;
            return this;
        }

        /**
         * 設(shè)置物體的初始下落速度
         * @param speed
         * @param isRandomSpeed 物體初始下降速度比例是否隨機(jī)
         * @return
         */
        public Builder setSpeed(int speed,boolean isRandomSpeed) {
            this.initSpeed = speed;
            this.isSpeedRandom = isRandomSpeed;
            return this;
        }

        /**
         * 設(shè)置物體大小
         * @param w
         * @param h
         * @return
         */
        public Builder setSize(int w, int h){
            this.bitmap = changeBitmapSize(this.bitmap,w,h);
            return this;
        }

        /**
         * 設(shè)置物體大小
         * @param w
         * @param h
         * @param isRandomSize 物體初始大小比例是否隨機(jī)
         * @return
         */
        public Builder setSize(int w, int h, boolean isRandomSize){
            this.bitmap = changeBitmapSize(this.bitmap,w,h);
            this.isSizeRandom = isRandomSize;
            return this;
        }
    }

    /**
     * 重置object位置
     */
    private void reset(){
        presentY = -objectHeight;
        randomSpeed();//記得重置時(shí)速度也一起重置至耻,這樣效果會(huì)好很多
    }

    /**
     * 隨機(jī)物體初始下落速度
     */
    private void randomSpeed(){
        if(isSpeedRandom){
            presentSpeed = (float)((random.nextInt(3)+1)*0.1+1)* initSpeed;//這些隨機(jī)數(shù)大家可以按自己的需要進(jìn)行調(diào)整
        }else {
            presentSpeed = initSpeed;
        }
    }

    /**
     * 隨機(jī)物體初始大小比例
     */
    private void randomSize(){
        if(isSizeRandom){
            float r = (random.nextInt(10)+1)*0.1f;
            float rW = r * builder.bitmap.getWidth();
            float rH = r * builder.bitmap.getHeight();
            bitmap = changeBitmapSize(builder.bitmap,(int)rW,(int)rH);
        }else {
            bitmap = builder.bitmap;
        }
        objectWidth = bitmap.getWidth();
        objectHeight = bitmap.getHeight();
    }
}

Activity中設(shè)置相應(yīng)參數(shù)即可

FallObject.Builder builder = new FallObject.Builder(getResources().getDrawable(R.drawable.ic_snow));
FallObject fallObject = builder
        .setSpeed(10,true)
        .setSize(50,50,true)
        .build();

效果如圖若皱,是不是看起來感覺好多了?乛?乛?


擴(kuò)展三:引入“風(fēng)”的概念

“風(fēng)”其實(shí)是一種比喻,實(shí)際上要做的是讓雪花除了做下落運(yùn)動(dòng)外尘颓,還會(huì)橫向移動(dòng)走触,也就是說我們要模擬出雪花在風(fēng)中亂舞的效果。為了讓雪花在X軸上的位移不顯得鬼畜(大家可以直接隨機(jī)增減x坐標(biāo)值就知道為什么是鬼畜了哈哈)疤苹,我們采用正弦函數(shù)來獲取X軸上的位移距離互广,如圖所示

正弦函數(shù)曲線見下圖

我們選取-π到π這段曲線,可以看出角的弧度在為π/2時(shí)正弦值最大(-π/2時(shí)最小)惫皱,因此我們?cè)谟?jì)算角度時(shí)還需要考慮其極限值像樊。同時(shí),因?yàn)槲覀兲砑恿藱M向的移動(dòng)旅敷,所以判斷邊界時(shí)要記得判定最左和最右的邊界凶硅,修改FallObject

public class FallObject {
    //省略部分代碼...
    public int initSpeed;//初始下降速度
    public int initWindLevel;//初始風(fēng)力等級(jí)
    
    private float angle;//物體下落角度
    
    private boolean isWindRandom;//物體初始風(fēng)向和風(fēng)力大小比例是否隨機(jī)
    private boolean isWindChange;//物體下落過程中風(fēng)向和風(fēng)力是否產(chǎn)生隨機(jī)變化

    private static final int defaultWindLevel = 0;//默認(rèn)風(fēng)力等級(jí)
    private static final int defaultWindSpeed = 10;//默認(rèn)單位風(fēng)速
    private static final float HALF_PI = (float) Math.PI / 2;//π/2

    public FallObject(Builder builder, int parentWidth, int parentHeight){
        //省略部分代碼...
        isWindRandom = builder.isWindRandom;
        isWindChange = builder.isWindChange;

        initSpeed = builder.initSpeed;
        randomSpeed();
        randomSize();
        randomWind();
    }

    private FallObject(Builder builder) {
        //省略部分代碼...
        isWindRandom = builder.isWindRandom;
        isWindChange = builder.isWindChange;
    }

    public static final class Builder {
        //省略部分代碼...
        private boolean isWindRandom;
        private boolean isWindChange;

        public Builder(Bitmap bitmap) {
            //省略部分代碼...
            this.isWindRandom = false;
            this.isWindChange = false;
        }

        public Builder(Drawable drawable) {
            //省略部分代碼...
            this.isWindRandom = false;
            this.isWindChange = false;
        }

        /**
         * 設(shè)置風(fēng)力等級(jí)、方向以及隨機(jī)因素
         * @param level 風(fēng)力等級(jí)(絕對(duì)值為 5 時(shí)效果會(huì)比較好)扫皱,為正時(shí)風(fēng)從左向右吹(物體向X軸正方向偏移)足绅,為負(fù)時(shí)則相反
         * @param isWindRandom 物體初始風(fēng)向和風(fēng)力大小比例是否隨機(jī)
         * @param isWindChange 在物體下落過程中風(fēng)的風(fēng)向和風(fēng)力是否會(huì)產(chǎn)生隨機(jī)變化
         * @return
         */
        public Builder setWind(int level,boolean isWindRandom,boolean isWindChange){
            this.initWindLevel = level;
            this.isWindRandom = isWindRandom;
            this.isWindChange = isWindChange;
            return this;
        }
    }

    /**
     * 移動(dòng)物體對(duì)象
     */
    private void moveObject(){
        moveX();
        moveY();
        if(presentY>parentHeight || presentX<-bitmap.getWidth() || presentX>parentWidth+bitmap.getWidth()){
            reset();
        }
    }

    /**
     * X軸上的移動(dòng)邏輯
     */
    private void moveX(){
        presentX += defaultWindSpeed * Math.sin(angle);
        if(isWindChange){
            angle += (float) (random.nextBoolean()?-1:1) * Math.random() * 0.0025;
        }
    }

    /**
     * 重置object位置
     */
    private void reset(){
        presentY = -objectHeight;
        randomSpeed();//記得重置時(shí)速度也一起重置,這樣效果會(huì)好很多
        randomWind();//記得重置一下初始角度韩脑,不然雪花會(huì)越下越少(因?yàn)榻嵌壤奂訒?huì)讓雪花越下越偏)
    }

    /**
     * 隨機(jī)風(fēng)的風(fēng)向和風(fēng)力大小比例氢妈,即隨機(jī)物體初始下落角度
     */
    private void randomWind(){
        if(isWindRandom){
            angle = (float) ((random.nextBoolean()?-1:1) * Math.random() * initWindLevel /50);
        }else {
            angle = (float) initWindLevel /50;
        }

        //限制angle的最大最小值
        if(angle>HALF_PI){
            angle = HALF_PI;
        }else if(angle<-HALF_PI){
            angle = -HALF_PI;
        }
    }
}

Activity中調(diào)用新增加的接口

FallObject.Builder builder = new FallObject.Builder(getResources().getDrawable(R.drawable.ic_snow));
FallObject fallObject = builder
        .setSpeed(7,true)
        .setSize(50,50,true)
        .setWind(5,true,true)
        .build();

效果如圖

至此本篇教程到此結(jié)束,如果大家看了感覺還不錯(cuò)麻煩點(diǎn)個(gè)贊段多,你們的支持是我最大的動(dòng)力~


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末首量,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子进苍,更是在濱河造成了極大的恐慌加缘,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件觉啊,死亡現(xiàn)場離奇詭異拣宏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杠人,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門勋乾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嗡善,你說我怎么就攤上這事辑莫。” “怎么了罩引?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵各吨,是天一觀的道長。 經(jīng)常有香客問我袁铐,道長揭蜒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任昭躺,我火速辦了婚禮忌锯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘领炫。我一直安慰自己,他們只是感情好张咳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布帝洪。 她就那樣靜靜地躺著似舵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葱峡。 梳的紋絲不亂的頭發(fā)上砚哗,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音砰奕,去河邊找鬼蛛芥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛军援,可吹牛的內(nèi)容都是我干的仅淑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胸哥,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼涯竟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起空厌,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤庐船,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后嘲更,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體筐钟,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年赋朦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盗棵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡北发,死狀恐怖纹因,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情琳拨,我是刑警寧澤瞭恰,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站狱庇,受9級(jí)特大地震影響扭勉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衅鹿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一愕够、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浪讳,春花似錦缰盏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽负溪。三九已至,卻和暖如春济炎,著一層夾襖步出監(jiān)牢的瞬間川抡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工须尚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留崖堤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓耐床,卻偏偏與公主長得像密幔,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咙咽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

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