項(xiàng)目需求討論-自定義滾輪

大家好侥袜,這次又是到了實(shí)際的項(xiàng)目需求討論時(shí)間蝌诡,我的一些文章下面,有時(shí)候有人評(píng)論枫吧,求源碼浦旱,求Demo,我的主張是仔細(xì)看文章九杂,自己理解了再寫一遍颁湖,會(huì)懂得更多。大部分人都習(xí)慣直接拿過來用例隆,能用了都不會(huì)去看為什么能實(shí)現(xiàn)需求甥捺。所以我還是寫以如何實(shí)現(xiàn)為主。(這B裝的我太累了镀层。我TM就是懶啊镰禾。不想寫Demo,自覺性還是有待提高鹿响。)

這次是關(guān)于滾輪方面需求羡微,美工又出難題了。叫開發(fā)做一個(gè)滾輪惶我,實(shí)現(xiàn)的效果如下GIF圖所示:

需求:

  1. 滾輪進(jìn)行滾動(dòng)妈倔,并且要求是循環(huán)滾動(dòng)。就是比如從A滑到了G绸贡,繼續(xù)滑動(dòng)又到了A盯蝴。
  2. 比如A開始滑動(dòng),滑到B听怕,但是你其實(shí)只滑動(dòng)了一點(diǎn)點(diǎn)捧挺,那放手后當(dāng)然是重新彈回A處,只有當(dāng)你滑動(dòng)的距離超過每項(xiàng)的一半的時(shí)候尿瞭,才能讓那一項(xiàng)滾到中間闽烙。
  3. 比如A項(xiàng)已經(jīng)滾到了中間了,然后要再點(diǎn)擊中間那一項(xiàng),然后滾輪上面空白界面相應(yīng)的界面會(huì)被更新黑竞,只能點(diǎn)擊滾輪中間那項(xiàng)部分捕发,其他的點(diǎn)擊沒效果。

開始起航:

我們就一步步來很魂,先做一個(gè)滾輪扎酷,我們知道,滾輪具有滾動(dòng)效果遏匆,所以我們就直接讓我們自定義滾輪繼承ScrollView法挨。從上面的GIF圖可知,我們的滾輪顯示在界面上的是有五項(xiàng)幅聘,也就是我們比如規(guī)定我們的每項(xiàng)的高度是50dp凡纳,那我們的自定義滾輪就是每項(xiàng)的高度乘以你要顯示在界面的個(gè)數(shù)(50dp X 5 = 250dp)。

我們先來繼承ScrollView:

public class WheelView extends ScrollView {
    public WheelView(Context context) {
        super(context);
        init(context);
    }

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

    }

    public WheelView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }
}

然后在init()方法中我們初始化滾輪具備的一些功能喊暖,比如我們上面的<需求2>

private LinearLayout views;
Runnable scrollerTask;
int initialY;

private void init(Context context) {
    this.context = context;

    this.setVerticalScrollBarEnabled(false);

    views = new LinearLayout(context);
    views.setOrientation(LinearLayout.VERTICAL);
    this.addView(views);

    scrollerTask = new Runnable() {

        public void run() {

            int newY = getScrollY();
            if (initialY - newY == 0) { // stopped
                final int remainder = initialY % itemHeight;
                final int divided = initialY / itemHeight;

                if (remainder == 0) {
                    selectedIndex = divided + offset;

                    onSeletedCallBack();
                } else {
                    if (remainder > itemHeight / 2) {
                        WheelView.this.post(new Runnable() {
                            @Override
                            public void run() {
                                WheelView.this.smoothScrollTo(0, initialY - remainder + itemHeight);
                                selectedIndex = divided + offset + 1;
                                onSeletedCallBack();
                            }
                            });
                    } else {
                        WheelView.this.post(new Runnable() {
                            @Override
                            public void run() {
                                WheelView.this.smoothScrollTo(0, initialY - remainder);
                                selectedIndex = divided + offset;
                                onSeletedCallBack();
                            }
                        });
                    }
                }
            } else {
                initialY = getScrollY();
                WheelView.this.postDelayed(scrollerTask, newCheck);
            }
        }
    };
}

我們來分析下我們的init()方法惫企,首先我們都知道ScrollView中只能有一個(gè)子控件,但我們滾輪里面有很多一項(xiàng)項(xiàng)的item陵叽,那怎么弄呢狞尔。 先在ScrollView中放一個(gè)LinearLayout,然后把我們要顯示的滾輪中的每一項(xiàng)再加入到這個(gè)LinearLayout中即可巩掺。同時(shí)大家也知道ScrollView本身在右邊會(huì)有一個(gè)顯示的滾動(dòng)條偏序,我們還要把這個(gè)滾動(dòng)條去除掉。代碼如下:

this.setVerticalScrollBarEnabled(false);

views = new LinearLayout(context);
views.setOrientation(LinearLayout.VERTICAL);
this.addView(views);

好了胖替,我們?cè)賮砜囱腥澹覀內(nèi)绾文軐?shí)現(xiàn)<需求2>


如何一格一格的滾動(dòng):

我們先來知道一個(gè)東西,如何讓他每次滾動(dòng)是滾一個(gè)Item呢独令,而不是說直接卡在一半端朵,就是說我直接劃動(dòng)一部分距離,然后ScrollView中的內(nèi)容就顯示成下面這個(gè)圖:


因?yàn)槲覀冎繱crollView的滾動(dòng)不是特定一格一格滾動(dòng)的燃箭,所以我們要用到了ScrollView中的smoothScrollTo方法了(可能有人會(huì)問冲呢,為啥不用ScrollTo,也可以,但是用smoothScrollTo滾動(dòng)的時(shí)候是平緩的而不是立即滾動(dòng)到某處)招狸。我們比如滑動(dòng)一部分敬拓。我們就讓ScrollView直接smoothScrollTo相應(yīng)的item的Y值處。這樣裙戏,就相當(dāng)于滑動(dòng)是一格一格的乘凸。

假設(shè)我們現(xiàn)在這個(gè)滾輪是只顯示3項(xiàng),假設(shè)每個(gè)的高度都是100累榜,然后我們比如往上滑营勤,比如讓C居于中間,我們只要smoothScrollTo(0,100),比如再往上移動(dòng)一格呢,就是smoothScrollTo(0,200),再往上移動(dòng)一格就是smoothScrollTo(0,300),也就是相當(dāng)于smoothScrollTo(0,(當(dāng)前的Y值)+(偏移的格數(shù) * 每格的高度))葛作,如果是向下移動(dòng)醒第,里面的偏移的格數(shù)就為負(fù)數(shù),當(dāng)前與當(dāng)前的Y值減去相應(yīng)的高度即可进鸠。


如何計(jì)算偏移格數(shù):

所以我們已經(jīng)解決了每次移動(dòng)的時(shí)候一定是一格一格的移動(dòng),而不會(huì)說滑動(dòng)了后形病,在二根紅線內(nèi)顯示一半的Item客年。接下去我們要處理如何定位我滑動(dòng)的時(shí)候來確定上述公式里面的偏移格數(shù)。

我們先來獲取你滾動(dòng)到哪里了:使用getScrollY(),所以當(dāng)我們滑動(dòng)了漠吻,我們就能獲取到我們這次滾動(dòng)到哪里了量瓜,這里我要分二塊來講:

  1. 慢慢的滑動(dòng) :
    慢慢滑動(dòng)的時(shí)候,我們獲取到的移動(dòng)距離就直接是getScrollY(),我們只需要監(jiān)聽onTouch事件途乃,然后在監(jiān)聽MotionEvent.ACTION_UP事件绍傲,當(dāng)監(jiān)聽到手指抬起來了。我們就通過getScrollY()獲取到這時(shí)候的滾動(dòng)的到哪里了耍共。

  2. 用力的滑動(dòng)后放開:
    這時(shí)候在監(jiān)聽MotionEvent.ACTION_UP事件的時(shí)候烫饼,你如果獲取了getScrollY的值,判定當(dāng)前滑動(dòng)到了這個(gè)位置是不準(zhǔn)確的试读,為什么杠纵,因?yàn)镾crollView還有因?yàn)閼T性在滑動(dòng),所以這時(shí)候我們要不停的獲取getScrollY的值钩骇,比如第一次取跟第二次取相比較比藻,如果不同,再取一次倘屹,每次都取了之后與前面一次取得值相比較银亲,如果相同,才能說明ScrollView已經(jīng)停下來了纽匙。這時(shí)候的距離才是真正的滾輪停止的位置务蝠。

所以我們?cè)诟鶕?jù)上面說的,我們重寫onTouch監(jiān)聽MotionEvent.ACTION_UP的事件:

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_UP) {
        startScrollerTask();
    }
    return super.onTouchEvent(ev);
}

int newCheck = 50;
public void startScrollerTask() {
    initialY = getScrollY();
    this.postDelayed(scrollerTask, newCheck);
}

我們獲取了手指放開時(shí)候的當(dāng)前ScrollView 所處的位置哄辣,然后延遲一點(diǎn)點(diǎn)時(shí)間后運(yùn)行了上面我們?cè)?code>init方法中自定義的Runnable请梢,因?yàn)榈葧?huì)這個(gè)Runnable里面會(huì)再次獲取ScrollView 的滾動(dòng)位置,要用來比較力穗,所以要延遲一點(diǎn)點(diǎn)時(shí)間毅弧。

我們來看下我們的自定義的Runnable的內(nèi)容:

scrollerTask = new Runnable() {

    public void run() {

        int newY = getScrollY();
        if (initialY - newY == 0) { // stopped
            final int remainder = initialY % itemHeight;
            final int divided = initialY / itemHeight;

            if (remainder == 0) {
                selectedIndex = divided + offset;

                onSeletedCallBack();
            } else {
                if (remainder > itemHeight / 2) {
                    WheelView.this.post(new Runnable() {
                        @Override
                        public void run() {
                            WheelView.this.smoothScrollTo(0, initialY - remainder + itemHeight);
                            selectedIndex = divided + offset + 1;
                            onSeletedCallBack();
                        }
                        });
                } else {
                    WheelView.this.post(new Runnable() {
                        @Override
                        public void run() {
                            WheelView.this.smoothScrollTo(0, initialY - remainder);
                            selectedIndex = divided + offset;
                            onSeletedCallBack();
                        }
                    });
                }
            }
        } else {
            initialY = getScrollY();
            WheelView.this.postDelayed(scrollerTask, newCheck);
        }
    }
};

我們發(fā)現(xiàn),我們?cè)赗unnable中再次調(diào)用了int newY = getScrollY();当窗,然后獲取了新的位置够坐,然后跟剛才在onTouch中獲取到的進(jìn)行比較,如果相同,說明ScrollView已經(jīng)停止了元咙。如果不同梯影,說明ScrollView還在滾動(dòng)中,我們要再次調(diào)用:

initialY = getScrollY();
WheelView.this.postDelayed(scrollerTask, newCheck);

然后再次重復(fù)執(zhí)行Runnable庶香,直到我們發(fā)現(xiàn)后面獲取到的getScrollY的值和延遲后獲取到的getScrollY的值相同甲棍,說明了我們的ScrollView已經(jīng)停止?jié)L動(dòng)了。這時(shí)候獲取到的getScrollY的值就是當(dāng)前這次滑動(dòng)后的ScrollView 真正處于的位置了赶掖。

到了我們核心的部分了:通過獲取到的ScrollView的滾動(dòng)位置來計(jì)算出當(dāng)前處于是哪個(gè)Item感猛,然后我們要來通過smoothScrollTo移動(dòng)這個(gè)到指定的Item項(xiàng)即可。

我們還是分二種情況分析:

  1. 第一種情況:



    我們還是來舉例子奢赂,綠色的框是我們的手機(jī)屏幕陪白,二根紅線就是我們中間項(xiàng)的分割線,比如我們?cè)瓉砥聊簧巷@示的是A,B,C 三項(xiàng)膳灶,我輕輕的往上移動(dòng)了80的距離咱士,這時(shí)候我們獲取到的getScrollY是80,
    我們通過拿到的getScrollY的值與每項(xiàng)的Item的高度做除法及求余算法轧钓。

final int remainder = initialY % itemHeight;
final int divided = initialY / itemHeight;

通過divided我們就知道了當(dāng)前屏幕上的能顯示的第一個(gè)是哪個(gè)Item了序厉。通過remainder我們就知道了屏幕的頂部處于這個(gè)Item的哪個(gè)位置。
比如當(dāng)前因?yàn)槲覀兊膅etScrollY是80毕箍,所以我們divided = 80 / 100 = 0;所以當(dāng)前屏幕上的顯示的第一個(gè)就是index為0的那項(xiàng)脂矫,也就是A;remainder = 80 % 100 = 80,所以我們知道顯示的第一項(xiàng)的大部分的都在屏幕外面了,只留下了(itemHeight - remainder ,即 100- 80 = 20)在屏幕里面霉晕。

這時(shí)候我要問大家了庭再,我放開手,這時(shí)候想要的效果應(yīng)該是什么牺堰,是不是A完全移出界面拄轻,然后B變成第一個(gè),C變中間伟葫,D變最后一個(gè)恨搓,這時(shí)候理論上調(diào)用的代碼應(yīng)該是smoothScrollTo(0,1 * itemHeight);也就是smoothScrollTo(0,100)。那這個(gè)1是怎么來的呢筏养。

if (remainder > itemHeight / 2) {
    WheelView.this.post(new Runnable() {
        @Override
            public void run() {
            WheelView.this.smoothScrollTo(0, initialY - remainder + itemHeight);
            ....
            ....
            ....
        }
    });
}

是不是因?yàn)槭俏覀兦笥鄶?shù)得到的remainder大于了50(itemHeight/2),所以本來第一個(gè)明明是A斧抱,我們卻讓B變成了第一個(gè),所以我們只需要把這個(gè)余數(shù)變?yōu)閕temHeight就行了渐溶。我們給他補(bǔ)上20辉浦,不就等于把A成功的移出屏幕了嗎? 所以不就是initialY - remainder + itemHeight茎辐。

  1. 第二種情況:

如果我們只是滾動(dòng)了一點(diǎn)點(diǎn)宪郊,比如我們這里只往上滾動(dòng)了20的距離掂恕,這時(shí)候getScrollY為20,我們這時(shí)候獲取到的

final int remainder = initialY % itemHeight;
final int divided = initialY / itemHeight;

remainder = 20,divided = 0,說明還是index為0的處于屏幕第一個(gè)弛槐,那這時(shí)候因?yàn)閞emainder 小于 itemHeight/2 ,所以我們的期望是讓A往下滾動(dòng)懊亡,然后屏幕上顯示為A,B,C ,
所以我們期望的是smoothScrollTo(0,0),也就是:

WheelView.this.post(new Runnable() {
    @Override
    public void run() {
        WheelView.this.smoothScrollTo(0, initialY - remainder);
        ....
        ....
        ....
    }
});

沒錯(cuò)乎串。既然多了20店枣,而且我們因?yàn)椴恍枰獫L動(dòng),直接把這個(gè)20減掉不就好了么叹誉。所以直接就是initailY - remainder艰争。


中間的紅線部分:

大家看見我上面的圖中,有二根紅線桂对。我不是故意把中間的一項(xiàng)給標(biāo)記出來,用二根紅線給提示下鸠匀,而是因?yàn)槊拦ぴO(shè)計(jì)的時(shí)候說蕉斜,默認(rèn)中間的是第一項(xiàng),而且是中間紅線包裹的地方才表示這一項(xiàng)處于選中狀態(tài)缀棍。因?yàn)楸緛砟J(rèn)的肯定是:

默認(rèn)的ScrollView 顯示
項(xiàng)目需求

不過既然原理我們上面都懂了宅此,我們還慌啥,其實(shí)很簡(jiǎn)單爬范,比如這個(gè)需求父腕,有屏幕上有三個(gè)Item,默認(rèn)是中間那個(gè)青瀑,我們只需要在A的前面多加一個(gè)空數(shù)據(jù)璧亮,在尾巴處也多加一個(gè)空數(shù)據(jù),即:[空數(shù)據(jù)斥难,A枝嘶,B,C哑诊,D群扶,E,空數(shù)據(jù)]镀裤。這樣ScrollView剛初始化好的時(shí)候竞阐,我們的A就處于中間位置了。有人會(huì)問為什么最后一個(gè)還要一個(gè)空數(shù)據(jù)暑劝,因?yàn)椴蝗荒阕詈笠豁?xiàng)E就不能顯示到中間紅線部分骆莹,就無法處于被選中狀態(tài)。

那如果一個(gè)屏幕顯示五項(xiàng)担猛,然后中間是選中的項(xiàng)汪疮,那就添加二個(gè):
[空數(shù)據(jù)峭火,空數(shù)據(jù),A智嚷,B卖丸,C,D盏道,E稍浆,空數(shù)據(jù),空數(shù)據(jù)]
哈哈猜嘱,是不是很簡(jiǎn)單衅枫。

所以你們會(huì)看到我上面的init方法中的代碼:
selectedIndex = divided + offset;類似的有出現(xiàn)過offset的這個(gè)值,也就是偏移值朗伶,因?yàn)槲覀儺?dāng)前默認(rèn)的選中的項(xiàng)不是第一項(xiàng)弦撩,而是中間這項(xiàng),比如我們本來的divided是0论皆,也就是屏幕第一個(gè)是A益楼,但是當(dāng)前A要處于中間才是選中裝填,我們只要設(shè)置offset = 1就可以了点晴。

往ScrollView里面加具體的Item:

上面我們已經(jīng)講了原理了「蟹铮現(xiàn)在我們就要往ScrollView中的LinearLayout里面加具體的Item,其實(shí)這個(gè)更簡(jiǎn)單了粒督。
我們?cè)谕饨缤覀兊淖远xScrollView中傳入列表數(shù)據(jù)陪竿,我這里用了普通的字符串:
(代碼里面的數(shù)據(jù)頭和尾巴補(bǔ)上偏移值上面剛講過,大家應(yīng)該還記得 )

public void setItems(List<String> list) {
    if (null == items) {
        items = new ArrayList<String>();
    }
    items.clear();
    items.addAll(list);

    // 前面和后面補(bǔ)全
    for (int i = 0; i < offset; i++) {
        items.add(0, "");
        items.add("");
    }

    initData();
}


int displayItemCount; // 每頁顯示的數(shù)量
private void initData() {
    displayItemCount = offset * 2 + 1;

    for (String item : items) {
        views.addView(createView(item));
    }
}


private TextView createView(String item) {

    TextView tv = new TextView(context);
    tv.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,dip2px(74)));
    tv.setSingleLine(true);
    tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
    tv.setText(item);
    tv.setGravity(Gravity.CENTER);
    int padding = dip2px(15);
    tv.setPadding(padding, padding, padding, padding);
    if (0 == itemHeight) {
        itemHeight = dip2px(74);
        Log.d(TAG, "itemHeight: " + itemHeight);
        views.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight * displayItemCount));
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.getLayoutParams();
        this.setLayoutParams(new LinearLayout.LayoutParams(lp.width, itemHeight * displayItemCount));
    }
    return tv;
}


中間的二根紅線怎么畫出來:

其實(shí)很簡(jiǎn)單屠橄,只要對(duì)ScrollView設(shè)置背景即可族跛,

然后背景的畫布上,在Y值為100處畫一根線锐墙,然后在Y值為200的地方畫一根線庸蔼,也就是:
一根在Y值為:itemHeight * offset;
一根在Y值為: itemHeight * (offset+1)即可;

@Override
public void setBackgroundDrawable(Drawable background) {
    if (viewWidth == 0) {
        viewWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();
    }

    if (null == paint) {
        paint = new Paint();
        paint.setColor(Color.parseColor("#83cde6"));
        paint.setStrokeWidth(dip2px(1f));
    }

    background = new Drawable() {
        @Override
        public void draw(Canvas canvas) {

            canvas.drawLine(viewWidth * 1 / 6, itemHeight * offset, viewWidth * 5 / 6, obtainSelectedAreaBorder()[0], paint);
            canvas.drawLine(viewWidth * 1 / 6, itemHeight * (offset+1), viewWidth * 5 / 6, obtainSelectedAreaBorder()[1], paint);

        }

        @Override
        public void setAlpha(int alpha) {

        }

        @Override
        public void setColorFilter(ColorFilter cf) {

        }

        @Override
        public int getOpacity() {
            return PixelFormat.UNKNOWN;
        }
    };
    
    super.setBackgroundDrawable(background);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    viewWidth = w;
    setBackgroundDrawable(null);
}

循環(huán)滾動(dòng):

其實(shí)我做的是一個(gè)假循環(huán),因?yàn)槲蚁氲搅搜h(huán)的Banner廣告贮匕,其實(shí)就是在頭部加一個(gè)最后一頁的數(shù)據(jù)姐仅,然后在尾部加第一個(gè)的數(shù)據(jù),滑到最后的時(shí)候刻盐,再滑動(dòng)掏膏,然后會(huì)跳到第一個(gè)。我也是用了這個(gè)思路敦锌。

還記不記得我們前面為了偏移值馒疹,所以多加了空數(shù)據(jù),我們就不弄空數(shù)據(jù)了乙墙,直接加真的數(shù)據(jù)颖变。
[A,B,C,D,E, A,B,C,D,E, A,B,C,D,E]
默認(rèn)顯示的是中間的A-E ,然后每次滑到不是中間的A-E生均,就默認(rèn)移動(dòng)回到中間的A-E就可以了。

然后把滾動(dòng)的速度減慢:

@Override
public void fling(int velocityY) {
    super.fling(velocityY / 5);
}

結(jié)語:

當(dāng)然我覺得這個(gè)假循環(huán)也不是最優(yōu)解腥刹。马胧。希望大家能提供思路。謝謝大家衔峰,不要噴我佩脊。如果不噴。晚些時(shí)候我整理下垫卤,放上GIF圖所示的Demo上來威彰。哈哈。不要噴我穴肘。歇盼。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末评抚,一起剝皮案震驚了整個(gè)濱河市豹缀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盈咳,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件边翼,死亡現(xiàn)場(chǎng)離奇詭異鱼响,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)组底,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門丈积,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人债鸡,你說我怎么就攤上這事江滨。” “怎么了厌均?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵唬滑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我棺弊,道長(zhǎng)晶密,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任模她,我火速辦了婚禮稻艰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侈净。我一直安慰自己尊勿,他們只是感情好僧凤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著元扔,像睡著了一般躯保。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上摇展,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天鲫售,我揣著相機(jī)與錄音,去河邊找鬼咱圆。 笑死卦羡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的祟滴。 我是一名探鬼主播振惰,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼垄懂!你這毒婦竟也來了骑晶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤草慧,失蹤者是張志新(化名)和其女友劉穎桶蛔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漫谷,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仔雷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了舔示。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碟婆。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惕稻,靈堂內(nèi)的尸體忽然破棺而出竖共,到底是詐尸還是另有隱情,我是刑警寧澤俺祠,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布公给,位于F島的核電站,受9級(jí)特大地震影響蜘渣,放射性物質(zhì)發(fā)生泄漏妓布。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一宋梧、第九天 我趴在偏房一處隱蔽的房頂上張望匣沼。 院中可真熱鬧,春花似錦捂龄、人聲如沸释涛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唇撬。三九已至它匕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窖认,已是汗流浹背豫柬。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扑浸,地道東北人烧给。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像喝噪,于是被迫代替她去往敵國(guó)和親础嫡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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