3CoordinatorLayout的measure和layout

本文分析下上篇文章的布局情況。CoordinatorLayout的布局跟普通viewgroup不太一樣搂擦,behavior會(huì)插一手稳诚。本篇主要介紹behavior如何影響measure和layout。

提出問(wèn)題

上文activity的xml如下

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.fish.behaviordemo.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_fab" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email"
        app:layout_behavior="com.fish.behaviordemo.fab.MyBehavior" />

</android.support.design.widget.CoordinatorLayout>

界面顯示效果如下所示

最外層是CoordinatorLayout瀑踢,里面放了個(gè)AppBarLayout扳还、content_fab才避、FloatingActionButton。我們先不管FloatingActionButton氨距。都說(shuō)CoordinatorLayout是個(gè)super FrameLayout桑逝,那這里的布局應(yīng)該是content_fab疊在AppBarLayout上咯?可是我們看到的是content_fab在AppBarLayout下方俏让,這可不像FrameLayout楞遏,難道是被蓋住了一部分沒(méi)看到嗎?錯(cuò)了,content_fab的的確卻是在AppBarLayout的下方首昔,這是CoordinatorLayout布局的時(shí)候定下來(lái)的寡喝。
我們這里的style如下,這個(gè)style的view tree內(nèi)是沒(méi)有statusbar的,可參考http://blog.csdn.net/litefish/article/details/52034813

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

那就有另一個(gè)問(wèn)題了勒奇,為何AppBarLayout不在屏幕的頂上预鬓,而在statubar的下方。
帶著這2個(gè)問(wèn)題赊颠,我們來(lái)看CoordinatorLayout的布局過(guò)程格二。
問(wèn)題1:為何AppBarLayout會(huì)在statusbar的下方
問(wèn)題2:為何content_fab在AppBarLayout的下方

列舉behavior

behavior是會(huì)介入onMeasure和onLayout過(guò)程的,我們先把各個(gè)子view的behavior找出來(lái)
AppBarLayout的behavior是由注解決定的
而content_fab的behavior是什么竣蹦?content_fab是個(gè)RelativeLayout顶猜,后文我們稱RelativeLayout。
xml內(nèi)有這么一句話

 app:layout_behavior="@string/appbar_scrolling_view_behavior"

@string/appbar_scrolling_view_behavior是什么?

    <string name="appbar_scrolling_view_behavior" translatable="false">android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>

其實(shí)從下面代碼可以看出是AppBarLayout.ScrollingViewBehavior

所以此處的CoordinatorLayout的3個(gè)子view和behavior如下所示

view behavior
AppBarLayout AppBarLayout.Behavior
RelativeLayout AppBarLayout.ScrollingViewBehavior
FloatingActionButton MyBehavior

我們不管FloatingActionButton草添,看AppBarLayout和RelativeLayout驶兜,都挺復(fù)雜的,下圖是累關(guān)系圖远寸,可以看到都是從ViewOffsetBehavior派生而來(lái)的抄淑。

再來(lái)看AppBarLayout.ScrollingViewBehavior內(nèi)的代碼,可以看到依賴于AppBarLayout驰后,所以這里RelativeLayout依賴于AppBarLayout

//AppBarLayout.ScrollingViewBehavior
      @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
            // We depend on any AppBarLayouts
            return dependency instanceof AppBarLayout;
        }

onMeasure分析

CoordinatorLayout的onMeasure方法如下所示肆资,比較簡(jiǎn)單,主要流程是灶芝,先算出insets的值郑原,然后measure的時(shí)候去掉這些insets,在measure 子view的時(shí)候犯犁,behavior先measure,返回false的話,才輪到view本身measure涣澡。
我們知道CoordinatorLayout是userRoot的根節(jié)點(diǎn)奄薇,所以第一次measure CoordinatorLayout的heightMeasureSpec.size是第一次用1668(1794-126),第二次用1794(1920-126)远搪。上邊這些數(shù)字都是在我手機(jī)上的值绷柒,1794是DisplayMetrics的高度值购披,126是navigatorbar的高度,1920是屏幕高度贮懈。
所以下邊代碼里躲因,onMeasure參數(shù)heightMeasureSpec的size第一次是1668秤标,第二次是1794。
下面開(kāi)始具體分析

   @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        prepareChildren();
        ensurePreDrawListener();
        。涩禀。爷怀。
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        final int widthPadding = paddingLeft + paddingRight;
        final int heightPadding = paddingTop + paddingBottom;
        ...

        final int childCount = mDependencySortedChildren.size();
        for (int i = 0; i < childCount; i++) {

            int childWidthMeasureSpec = widthMeasureSpec;
            int childHeightMeasureSpec = heightMeasureSpec;
            if (applyInsets && !ViewCompat.getFitsSystemWindows(child)) {
                // We're set to handle insets but this child isn't, so we will measure the
                // child as if there are no insets
                final int horizInsets = mLastInsets.getSystemWindowInsetLeft()
                        + mLastInsets.getSystemWindowInsetRight();
                //獲取vertInsets值锦溪,其實(shí)這里就是statubar的高度
                final int vertInsets = mLastInsets.getSystemWindowInsetTop()
                        + mLastInsets.getSystemWindowInsetBottom();

                childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
                        widthSize - horizInsets, widthMode);
                childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        heightSize - vertInsets, heightMode);
            }

            final Behavior b = lp.getBehavior();
            //behavior先measure峦剔,返回false的話,才輪到view本身measure
            if (b == null || !b.onMeasureChild(this, child, childWidthMeasureSpec, keylineWidthUsed,
                    childHeightMeasureSpec, 0)) {
                onMeasureChild(child, childWidthMeasureSpec, keylineWidthUsed,
                        childHeightMeasureSpec, 0);
            }
        }

        。栅受。。
    }

    final int width = ViewCompat.resolveSizeAndState(widthUsed, widthMeasureSpec,
            childState & ViewCompat.MEASURED_STATE_MASK);
    final int height = ViewCompat.resolveSizeAndState(heightUsed, heightMeasureSpec,
            childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);

    setMeasuredDimension(width, height);
}

第一次measure,heightMeasureSpec.size為1668
prepareChildren和ensurePreDrawListener,之前在 這里分析過(guò),不清楚的可以回顧下睛琳。
因?yàn)樽觱iew沒(méi)有寫(xiě)fitsSystemWindows辟癌,所以L20會(huì)進(jìn)去荐捻,在L23會(huì)算出vertInsets黍少,這里實(shí)際就是statubar的高度(63)厂置。然后L29访忿,修改childHeightMeasureSpec.size為1668-63=1605游添。從這里可以看出在measure的過(guò)程中,其實(shí)是除掉了statubar的高度廊酣,然后走到L35能耻,先交給behavior measure。這里我們主要看下RelativeLayout這個(gè)child是如何measure的凡辱,RelativeLayout的behavior是AppBarLayout.ScrollingViewBehavior戒职,他沒(méi)有復(fù)寫(xiě)onMeasureChild方法,所以看父類HeaderScrollingViewBehavior透乾。先看L7洪燥,只有MATCH_PARENT或WRAP_CONTENT,我們behavior才處理乳乌,否則直接返回false捧韵,丟給view自己處理,我們這里是MATCH_PARENT汉操,由behavior處理再来。 然后看L13,找到一個(gè)header客情,這是個(gè)view其弊,這個(gè)非常重要,是當(dāng)前view的第一個(gè)依賴view(可以稱為header)膀斋,當(dāng)前view的各種操作都會(huì)依賴于header,明顯痹雅,我們的RelativeLayout的header就是AppBarLayout仰担,再看L28,如果head沒(méi)有l(wèi)ayout過(guò)绩社,那直接返回false摔蓝,意思就是必須在head 布局完成之后,再來(lái)measure我們RelativeLayout愉耙。這個(gè)行為是比較奇怪的贮尉,一個(gè)view的measure居然依賴另一個(gè)view的layout。此時(shí)朴沿,我們肯定沒(méi)有l(wèi)ayout過(guò)猜谚,所以直接返回false败砂,然后走上邊代碼的L39,之后RelativeLayout的measuredHeight變?yōu)?605.

第二次measure魏铅,先看上文代碼昌犹,heightMeasureSpec.size為1794,在L28改為1794-63=1731览芳,進(jìn)入下邊代碼斜姥,此時(shí)header還沒(méi)layout,所以返回false沧竟,依然是view自身measure铸敏,之后RelativeLayout的measuredHeight變?yōu)?794.

上2次measure都在layout之前,是通過(guò)view本身來(lái)measure的悟泵,我們?cè)诳纯磍ayout之后的measure

第三次measure(這次measure是怎么觸發(fā)的呢搞坝?),此時(shí)已經(jīng)layout過(guò)了
先看上文代碼魁袜,heightMeasureSpec.size為1794桩撮,在L29改為1794-63=1731,進(jìn)入下邊代碼峰弹,此時(shí)header已經(jīng)layout店量,所以進(jìn)入L28的if內(nèi),重點(diǎn)關(guān)注L35鞠呈,

final int height = availableHeight - header.getMeasuredHeight()
+ getScrollRange(header);
翻一下就是parent的高度-header的measuredHeight+header的滾動(dòng)范圍

這里減掉了一個(gè)header.getMeasuredHeight()融师,加上了getScrollRange(header),后者我們暫時(shí)不考慮蚁吝,此時(shí)其實(shí)就是減去了AppBarlayout的measuredHeight旱爆,在這里就是1731-147=1584,然后調(diào)用 CoordinatorLayout.onMeasureChild窘茁,最后measure結(jié)果就是1584怀伦,下邊代碼返回true。這其實(shí)是HeaderScrollingViewBehavior的一個(gè)特性山林,讓當(dāng)前view處于header的下方房待。

好了,三輪measure下來(lái)驼抹,最終RelativeLayout的measuredHeight被定為1584

//HeaderScrollingViewBehavior
    @Override
    public boolean onMeasureChild(CoordinatorLayout parent, View child,
            int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec,
            int heightUsed) {
        final int childLpHeight = child.getLayoutParams().height;
        if (childLpHeight == ViewGroup.LayoutParams.MATCH_PARENT
                || childLpHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
            // If the menu's height is set to match_parent/wrap_content then measure it
            // with the maximum visible height

            final List<View> dependencies = parent.getDependencies(child);
            final View header = findFirstDependency(dependencies);
            if (header != null) {
                if (ViewCompat.getFitsSystemWindows(header)
                        && !ViewCompat.getFitsSystemWindows(child)) {
                    // If the header is fitting system windows then we need to also,
                    // otherwise we'll get CoL's compatible measuring
                    ViewCompat.setFitsSystemWindows(child, true);

                    if (ViewCompat.getFitsSystemWindows(child)) {
                        // If the set succeeded, trigger a new layout and return true
                        child.requestLayout();
                        return true;
                    }
                }
                   //header未layout桑孩,我就不measure
                if (ViewCompat.isLaidOut(header)) {
                    int availableHeight = View.MeasureSpec.getSize(parentHeightMeasureSpec);
                    if (availableHeight == 0) {
                        // If the measure spec doesn't specify a size, use the current height
                        availableHeight = parent.getHeight();
                    }

                    final int height = availableHeight - header.getMeasuredHeight()
                            + getScrollRange(header);
                    final int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(height,
                            childLpHeight == ViewGroup.LayoutParams.MATCH_PARENT
                                    ? View.MeasureSpec.EXACTLY
                                    : View.MeasureSpec.AT_MOST);

                    // Now measure the scrolling view with the correct height
                    parent.onMeasureChild(child, parentWidthMeasureSpec,
                            widthUsed, heightMeasureSpec, heightUsed);

                    return true;
                }
            }
        }
        return false;
    }

onLayout分析

看下邊CoordinatorLayout的onLayout,發(fā)現(xiàn)布局的子view的時(shí)候框冀,先由behavior處理流椒,behavior未處理成功再交給child處理准夷,跟onMeasure類似贯钩。

 @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int layoutDirection = ViewCompat.getLayoutDirection(this);
        final int childCount = mDependencySortedChildren.size();
        for (int i = 0; i < childCount; i++) {
            final View child = mDependencySortedChildren.get(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            final Behavior behavior = lp.getBehavior();

            if (behavior == null || !behavior.onLayoutChild(this, child, layoutDirection)) {
                onLayoutChild(child, layoutDirection);
            }
        }
    }

我們?cè)賮?lái)分析瞧毙,因?yàn)镽elativeLayout依賴于AppBarLayout六敬,所以在mDependencySortedChildren內(nèi),AppBarLayout在前安岂,RelativeLayout在后轻猖。

布局AppBarLayout

先看如何布局AppBarLayout。

step1

看AppBarLayout.Behavior的onLayoutChild域那,首先調(diào)用了super.onLayoutChild咙边,會(huì)調(diào)用到ViewOffsetBehavior的onLayoutChild

      //AppBarLayout.Behavior
      @Override
        public boolean onLayoutChild(CoordinatorLayout parent, AppBarLayout abl,
                int layoutDirection) {
            boolean handled = super.onLayoutChild(parent, abl, layoutDirection);
            ...
        }

step2

再看ViewOffsetBehavior的onLayoutChild,調(diào)用layoutChild次员,然后調(diào)用parent.onLayoutChild败许,parent是誰(shuí),CoordinatorLayout

   public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
        // First let lay the child out
        layoutChild(parent, child, layoutDirection);

        if (mViewOffsetHelper == null) {
            mViewOffsetHelper = new ViewOffsetHelper(child);
        }
        mViewOffsetHelper.onViewLayout();

        if (mTempTopBottomOffset != 0) {
            mViewOffsetHelper.setTopAndBottomOffset(mTempTopBottomOffset);
            mTempTopBottomOffset = 0;
        }
        if (mTempLeftRightOffset != 0) {
            mViewOffsetHelper.setLeftAndRightOffset(mTempLeftRightOffset);
            mTempLeftRightOffset = 0;
        }

        return true;
    }
     
       protected void layoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
        // Let the parent lay it out by default
        parent.onLayoutChild(child, layoutDirection);
    }

step3

CoordinatorLayout的onLayoutChild一般會(huì)調(diào)用layoutChild淑蔚,看完這段代碼市殷,就應(yīng)該能明白問(wèn)題1。里面有個(gè)parent叫Rect刹衫,這個(gè)Rect代表CoordinatorLayout內(nèi)部可以放子view的空間醋寝,一開(kāi)始的時(shí)候parent的top為0,在L15把statusbar的高度加到top里去带迟,這其實(shí)就是為了讓AppbarLayout不要和statusbar重疊音羞。在L21根據(jù)AppbarLayout的getMeasuredHeight()和parent,算出一個(gè)Rect out仓犬,用這個(gè)Rect來(lái)給AppbarLayout布局嗅绰,out里的top必定是statusbar的高度,在L23 child.layout內(nèi)AppbarLayout的mTop必然被設(shè)置為statusbar的高度搀继,所以問(wèn)題1解決窘面,核心代碼就是layoutChild。注意layoutChild不是針對(duì)AppbarLayout叽躯,所以任何子view都不可能跑到statubar上财边。

    private void layoutChild(View child, int layoutDirection) {
        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        final Rect parent = mTempRect1;
        parent.set(getPaddingLeft() + lp.leftMargin,
                getPaddingTop() + lp.topMargin,
                getWidth() - getPaddingRight() - lp.rightMargin,
                getHeight() - getPaddingBottom() - lp.bottomMargin);

        if (mLastInsets != null && ViewCompat.getFitsSystemWindows(this)
                && !ViewCompat.getFitsSystemWindows(child)) {
            // If we're set to handle insets but this child isn't, then it has been measured as
            // if there are no insets. We need to lay it out to match.
            parent.left += mLastInsets.getSystemWindowInsetLeft();
            //這里把statusbar的高度算進(jìn)去了
            parent.top += mLastInsets.getSystemWindowInsetTop();
            parent.right -= mLastInsets.getSystemWindowInsetRight();
            parent.bottom -= mLastInsets.getSystemWindowInsetBottom();
        }

        final Rect out = mTempRect2;
        GravityCompat.apply(resolveGravity(lp.gravity), child.getMeasuredWidth(),
                child.getMeasuredHeight(), parent, out, layoutDirection);
        child.layout(out.left, out.top, out.right, out.bottom);
    }

step4 mViewOffsetHelper.onViewLayout

此時(shí),其實(shí)相當(dāng)于給AppBarLayout設(shè)置了一個(gè)額外的padding险毁,這個(gè)值會(huì)被記錄下來(lái)制圈,在onLayoutChild的L8,有mViewOffsetHelper.onViewLayout.由下邊代碼可知mLayoutTop就記錄了這個(gè)額外的padding畔况。ViewOffsetHelper內(nèi)部有mLayoutTop,mOffsetTop慧库。mLayoutTop代表基本top跷跪,mOffsetTop代表額外top偏移量,實(shí)際view的top為 mLayoutTop+ mOffsetTop齐板。ViewOffsetHelper內(nèi)的setTopAndBottomOffset的參數(shù)offset是一個(gè)絕對(duì)值吵瞻,但是view的offsetTopAndBottom的參數(shù)offset是一個(gè)delta值葛菇,mLayoutTop就可以把絕對(duì)值轉(zhuǎn)化為delta值。

    public void onViewLayout() {
        // Now grab the intended top
        mLayoutTop = mView.getTop();
        mLayoutLeft = mView.getLeft();

        // And offset it as needed
        updateOffsets();
    }

布局RelativeLayout

RelativeLayout的behavior是AppBarLayout.ScrollingViewBehavior

step1

和布局AppBarLayout一樣橡羞,會(huì)調(diào)用ViewOffsetBehavior的onLayoutChild

step2

ViewOffsetBehavior的onLayoutChild眯停,調(diào)用layoutChild,此時(shí)layoutChild可不一樣了,因?yàn)镠eaderScrollingViewBehavior復(fù)寫(xiě)了卿泽≥赫看下邊代碼可以解決我們的第二個(gè)問(wèn)題,首先尋找依賴的view签夭,我們的RelativeLayout依賴AppBarLayout齐邦,然后看L13,這個(gè)代碼非常關(guān)鍵第租,available這個(gè)Rect設(shè)置在AppBarLayout的下方措拇,然后類似的在L20啊,根據(jù)getMeasuredHeight()和available計(jì)算出out慎宾,再用out來(lái)layout RelativeLayout丐吓。所以RelativeLayout必然在AppBarLayout的下方,這是由它的behavior決定的趟据。HeaderScrollingViewBehavior要求排在首個(gè)依賴view(header)的下方

 @Override
    protected void layoutChild(final CoordinatorLayout parent, final View child,
            final int layoutDirection) {
        final List<View> dependencies = parent.getDependencies(child);
        //尋找依賴
        final View header = findFirstDependency(dependencies);

        if (header != null) {
            final CoordinatorLayout.LayoutParams lp =
                    (CoordinatorLayout.LayoutParams) child.getLayoutParams();
            final Rect available = mTempRect1;
            //這個(gè)rect在依賴view的下邊
            available.set(parent.getPaddingLeft() + lp.leftMargin,
                    header.getBottom() + lp.topMargin,
                    parent.getWidth() - parent.getPaddingRight() - lp.rightMargin,
                    parent.getHeight() + header.getBottom()
                            - parent.getPaddingBottom() - lp.bottomMargin);

            final Rect out = mTempRect2;
            GravityCompat.apply(resolveGravity(lp.gravity), child.getMeasuredWidth(),
                    child.getMeasuredHeight(), available, out, layoutDirection);

            final int overlap = getOverlapPixelsForOffset(header);

            child.layout(out.left, out.top - overlap, out.right, out.bottom - overlap);
            mVerticalLayoutGap = out.top - header.getBottom();
        } else {
            // If we don't have a dependency, let super handle it
            super.layoutChild(parent, child, layoutDirection);
            mVerticalLayoutGap = 0;
        }
    }

總結(jié)

1券犁、CoordinatorLayout像一個(gè)FrameLayout,但是里面的布局受behavior影響之宿,我們可以通過(guò)改寫(xiě)behavior來(lái)修改布局策略
2族操、CoordinatorLayout的高度包括statubar,如果CoordinatorLayout的子view沒(méi)有寫(xiě)fitsSystemWindows比被,都不可能跑到statubar上色难,因?yàn)閙easure的時(shí)候會(huì)除掉statubar,layoutChild的時(shí)候也會(huì)處理等缀。
3枷莉、如果CoordinatorLayout的子view重寫(xiě)了fitsSystemWindows,那么子view的范圍會(huì)包括statubar
4尺迂、HeaderScrollingViewBehavior有個(gè)特性笤妙,使用此behavior的view 必然排在他的首個(gè)依賴view(簡(jiǎn)稱header)的下方,因?yàn)閺?fù)寫(xiě)了layoutChild

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末噪裕,一起剝皮案震驚了整個(gè)濱河市蹲盘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌膳音,老刑警劉巖召衔,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異祭陷,居然都是意外死亡苍凛,警方通過(guò)查閱死者的電腦和手機(jī)趣席,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)醇蝴,“玉大人宣肚,你說(shuō)我怎么就攤上這事∮扑ǎ” “怎么了霉涨?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)闸迷。 經(jīng)常有香客問(wèn)我嵌纲,道長(zhǎng),這世上最難降的妖魔是什么腥沽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任逮走,我火速辦了婚禮,結(jié)果婚禮上今阳,老公的妹妹穿的比我還像新娘师溅。我一直安慰自己,他們只是感情好盾舌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布墓臭。 她就那樣靜靜地躺著,像睡著了一般妖谴。 火紅的嫁衣襯著肌膚如雪窿锉。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,231評(píng)論 1 299
  • 那天洼滚,我揣著相機(jī)與錄音铲掐,去河邊找鬼斯入。 笑死磅摹,一個(gè)胖子當(dāng)著我的面吹牛帝美,可吹牛的內(nèi)容都是我干的舰褪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起何什,我...
    開(kāi)封第一講書(shū)人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荠诬,失蹤者是張志新(化名)和其女友劉穎涛浙,沒(méi)想到半個(gè)月后轿亮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體我注,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞳步,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年氛堕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绕沈。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锐想,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乍狐,到底是詐尸還是另有隱情赠摇,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布浅蚪,位于F島的核電站藕帜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏惜傲。R本人自食惡果不足惜洽故,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盗誊。 院中可真熱鬧时甚,春花似錦、人聲如沸哈踱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)开镣。三九已至刀诬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邪财,已是汗流浹背陕壹。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卧蜓,地道東北人帐要。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像弥奸,于是被迫代替她去往敵國(guó)和親榨惠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

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