Android-DecorView-一窺全貌(下)

前言

上篇分析了DecorView創(chuàng)建過(guò)程轻要,大致說(shuō)了其子View構(gòu)成链嘀,還剩下一些疑點(diǎn),本篇繼續(xù)分析。
上篇文章:Android DecorView 一窺全貌(上)

通過(guò)本篇文章聂沙,你將了解到:

1、DecorView各個(gè)子View具體布局內(nèi)容
2初嘹、狀態(tài)欄(背景)和導(dǎo)航欄(背景)如何添加到DecorView里
3及汉、DecorView子View位置與大小的確定
4、常見(jiàn)的獲取DecorView各個(gè)區(qū)塊大小的方法

DecorView各個(gè)子View具體布局內(nèi)容

照舊屯烦,打開(kāi)Tools->Layout Inspector


image.png

此時(shí)坷随,DecorView有三個(gè)子View,分別是LinearLayout驻龟、navigationBarBackground温眉、statusBarBackground。

默認(rèn)DecorView布局

先來(lái)看看LinearLayout翁狐,之前分析過(guò)加載DecorView時(shí)类溢,根據(jù)不同的feature確定不同的布局,我們的demo加載的是默認(rèn)布局:R.layout.screen_simple露懒。
這是系統(tǒng)自帶的布局文件闯冷,在哪找呢?

切換到Project模式——>找到External Libraries——>對(duì)應(yīng)的編譯API——>res library root——>layout文件夾下——>尋找對(duì)應(yīng)的布局名

R.layout.screen_simple布局內(nèi)容

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">
    <ViewStub android:id="@+id/action_mode_bar_stub"
              android:inflatedId="@+id/action_mode_bar"
              android:layout="@layout/action_mode_bar"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:theme="?attr/actionBarTheme" />
    <FrameLayout
         android:id="@android:id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:foregroundInsidePadding="false"
         android:foregroundGravity="fill_horizontal|top"
         android:foreground="?android:attr/windowContentOverlay" />
</LinearLayout>

幾點(diǎn)有價(jià)值的地方:

  • 該LinearLayout方向是垂直的懈词,有個(gè)屬性android:fitsSystemWindows="true"(后續(xù)需要用到)
  • ViewStub是占位用的蛇耀,默認(rèn)是Gone,先不管
  • 有個(gè)id="content"的FrameLayout坎弯,是不是有點(diǎn)熟悉纺涤?

再來(lái)看看實(shí)際的layout展示:


image.png

正好和LinearLayout對(duì)應(yīng),ViewStub也對(duì)得上抠忘,但是明明布局文件里的FrameLayout是沒(méi)有子View的撩炊,實(shí)際怎么會(huì)有呢?當(dāng)然是中途動(dòng)態(tài)添加進(jìn)去的褐桌。

SubDecor

之前分析過(guò),DecorView創(chuàng)建成功后象迎,又繼續(xù)加載了一個(gè)布局:R.layout.abc_screen_toolbar荧嵌,并賦予subDecor變量,最后將subDecor里的某個(gè)子View添加到DecorView里砾淌。那么該布局文件在哪找呢啦撮?按照上面的方法,你會(huì)發(fā)現(xiàn)layout里并沒(méi)有對(duì)應(yīng)的布局文件汪厨。

實(shí)際上加載R.layout.abc_screen_toolbar是由AppCompatDelegateImpl.java完成的赃春,而該類屬于androidx.appcompat.app包,因此該尋找androidx里資源文件

image.png

R.layout.abc_screen_toolbar布局內(nèi)容:

<androidx.appcompat.widget.ActionBarOverlayLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/decor_content_parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
    <include layout="@layout/abc_screen_content_include"/>
    <androidx.appcompat.widget.ActionBarContainer
            android:id="@+id/action_bar_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            style="?attr/actionBarStyle"
            android:touchscreenBlocksFocus="true"
            android:gravity="top">
        <androidx.appcompat.widget.Toolbar
                android:id="@+id/action_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
         app:navigationContentDescription="@string/abc_action_bar_up_description"
                style="?attr/toolbarStyle"/>
        <androidx.appcompat.widget.ActionBarContextView
                android:id="@+id/action_context_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:theme="?attr/actionBarTheme"
                style="?attr/actionModeStyle"/>
    </androidx.appcompat.widget.ActionBarContainer>
</androidx.appcompat.widget.ActionBarOverlayLayout>

同樣提取幾個(gè)關(guān)鍵信息:

  • ActionBarOverlayLayout 繼承自ViewGroup劫乱,id="decor_content_parent"织中,同樣有個(gè)屬性:android:fitsSystemWindows="true"
  • ActionBarContainer顧名思義是容納ActionBar的锥涕,id="action_bar_container",android:gravity="top"狭吼。繼承自FrameLayout层坠。有兩個(gè)子View,一個(gè)是ToolBar刁笙,另一個(gè)是ActionBar∑苹ǎ現(xiàn)在高版本都使用ToolBar替代ActionBar。

ActionBarOverlayLayout還有個(gè)子View

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

其內(nèi)容為:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <androidx.appcompat.widget.ContentFrameLayout
            android:id="@id/action_bar_activity_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:foregroundGravity="fill_horizontal|top"
            android:foreground="?android:attr/windowContentOverlay" />
</merge>
  • ContentFrameLayout繼承自FrameLayout疲吸,id="action_bar_activity_content"

以上座每,DecorView默認(rèn)布局文件和SubDecor布局文件已經(jīng)分析完畢,接下來(lái)看看SubDecor如何添加到DecorView里摘悴。

        //尋找subDecor子布局峭梳,命名為contentView
        final ContentFrameLayout contentView = (ContentFrameLayout) subDecor.findViewById(
                R.id.action_bar_activity_content);
        //找到window里content布局,實(shí)際上找的是DecorView里名為content的布局
        final ViewGroup windowContentView = (ViewGroup) mWindow.findViewById(android.R.id.content);
        if (windowContentView != null) {
            //挨個(gè)移除windowContentView的子View烦租,并將之添加到contentView里
            while (windowContentView.getChildCount() > 0) {
                final View child = windowContentView.getChildAt(0);
                windowContentView.removeViewAt(0);
                contentView.addView(child);
            }
            //把windowContentView id去掉延赌,之前名為content
            windowContentView.setId(View.NO_ID);
            //將"content"名賦予contentView
            contentView.setId(android.R.id.content);
        }
        //把subDecor添加為Window的contentView,實(shí)際上添加為DecorView的子View叉橱。該方法后面再具體分析
        mWindow.setContentView(subDecor);

1挫以、首先從subDecor里尋找R.id.action_bar_activity_content,屬于subDecor子View窃祝,其繼承自FrameLayout掐松。
2、再?gòu)腄ecorView里尋找android.R.id.content粪小,是FrameLayout
3大磺、移除android.R.id.content里的子View,并將其添加到R.id.action_bar_activity_content里(當(dāng)然此時(shí)content沒(méi)有子View)
4探膊、把"android.R.id.content"這名替換掉R.id.action_bar_activity_content
5杠愧、最后將subDecor添加到FrameLayout里,對(duì)就是名字被換掉了的布局逞壁。

此時(shí)DecorView和subDecor已經(jīng)結(jié)合了流济,并且android.R.id.content也存在,我們?cè)趕etContentView(xx)里設(shè)置的layout會(huì)被添加到android.R.id.content里腌闯。

狀態(tài)欄(背景)和導(dǎo)航欄(背景)

前面只是分析了LinearLayout及其子View的構(gòu)造绳瘟,而DecorView還有另外兩個(gè)子View:狀態(tài)欄(背景)/導(dǎo)航欄(背景)沒(méi)有提及,接下來(lái)看看它們是如何關(guān)聯(lián)上的姿骏。
既然是DecorView的子View糖声,那么必然有個(gè)addView()的過(guò)程,搜索后確定如下方法:

DecorView.java
    private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
                                    int dividerColor, int size, boolean verticalBar, boolean seascape, int sideMargin,
                                    boolean animate, boolean force) {
        View view = state.view;
        //確定View的寬高
        int resolvedHeight = verticalBar ? LayoutParams.MATCH_PARENT : size;
        int resolvedWidth = verticalBar ? size : LayoutParams.MATCH_PARENT;
        //確定View的Gravity
        int resolvedGravity = verticalBar
                ? (seascape ? state.attributes.seascapeGravity : state.attributes.horizontalGravity)
                : state.attributes.verticalGravity;

        if (view == null) {
            if (showView) {
                //構(gòu)造View
                state.view = view = new View(mContext);
                //設(shè)置View背景色
                setColor(view, color, dividerColor, verticalBar, seascape);
                //設(shè)置id
                view.setId(state.attributes.id);
                LayoutParams lp = new LayoutParams(resolvedWidth, resolvedHeight,
                        resolvedGravity);
                //添加到DecorView
                addView(view, lp);
            }
        } else {
            //省略...
        }
        //省略
    }

該方法根據(jù)條件添加子View到DecorView,調(diào)用該方法的地方有兩處:

DecorView.java
    WindowInsets updateColorViews(WindowInsets insets, boolean animate) {
        WindowManager.LayoutParams attrs = mWindow.getAttributes();
        //控制狀態(tài)欄蘸泻、導(dǎo)航欄標(biāo)記
        int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();

        if (!mWindow.mIsFloating || isImeWindow) {
            //insets記錄著狀態(tài)欄琉苇、導(dǎo)航欄、高度
            if (insets != null) {
                //四個(gè)邊界的偏移
                mLastTopInset = getColorViewTopInset(insets.getStableInsetTop(),
                        insets.getSystemWindowInsetTop());
                mLastBottomInset = getColorViewBottomInset(insets.getStableInsetBottom(),
                        insets.getSystemWindowInsetBottom());
                mLastRightInset = getColorViewRightInset(insets.getStableInsetRight(),
                        insets.getSystemWindowInsetRight());
                mLastLeftInset = getColorViewRightInset(insets.getStableInsetLeft(),
                        insets.getSystemWindowInsetLeft());
                //省略..
            }
            //省略
            //導(dǎo)航欄高度
            int navBarSize = getNavBarSize(mLastBottomInset, mLastRightInset, mLastLeftInset);
            //添加/設(shè)置導(dǎo)航欄
            updateColorViewInt(mNavigationColorViewState, sysUiVisibility,
                    calculateNavigationBarColor(), mWindow.mNavigationBarDividerColor, navBarSize,
                    navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge,
                    0 /* sideInset */, animate && !disallowAnimate,
                    mForceWindowDrawsBarBackgrounds);
            //添加設(shè)置狀態(tài)欄
            updateColorViewInt(mStatusColorViewState, sysUiVisibility,
                    calculateStatusBarColor(), 0, mLastTopInset,
                    false /* matchVertical */, statusBarNeedsLeftInset, statusBarSideInset,
                    animate && !disallowAnimate,
                    mForceWindowDrawsBarBackgrounds);
        }
        //省略 主要和和全屏蟋恬、隱藏等屬性相關(guān)的
        
        //mContentRoot是DecorView的第一個(gè)子View
        //也即是LinearLayout翁潘,根據(jù)狀態(tài)欄、導(dǎo)航欄高度調(diào)整LinearLayout高度
        if (mContentRoot != null
                && mContentRoot.getLayoutParams() instanceof MarginLayoutParams) {
            MarginLayoutParams lp = (MarginLayoutParams) mContentRoot.getLayoutParams();
            if (lp.topMargin != consumedTop || lp.rightMargin != consumedRight
                    || lp.bottomMargin != consumedBottom || lp.leftMargin != consumedLeft) {
                lp.topMargin = consumedTop;
                lp.rightMargin = consumedRight;
                lp.bottomMargin = consumedBottom;
                lp.leftMargin = consumedLeft;
                mContentRoot.setLayoutParams(lp);
            }
        }
        return insets;
    }

提取要點(diǎn)如下:

  • 狀態(tài)欄歼争、導(dǎo)航欄是屬于View拜马,而不是ViewGroup。因此不能再添加任何子View沐绒,這也就是為什么稱為:狀態(tài)欄背景俩莽,導(dǎo)航欄背景的原因。實(shí)際上乔遮,DecorView里設(shè)置的這兩個(gè)背景是為了占位使用的扮超。
  • 狀態(tài)欄、導(dǎo)航欄高度是系統(tǒng)確定的蹋肮,在ViewRootImpl->setView(xx)出刷,獲取到其邊界屬性。
  • DecorView有三個(gè)子View坯辩,LinearLayout(內(nèi)容)馁龟、狀態(tài)欄、導(dǎo)航欄漆魔。LinearLayout根據(jù)后兩者狀態(tài)調(diào)整自身的LayoutParms坷檩。比如此時(shí)LinearLayout bottomMargin=126(導(dǎo)航欄高度)。
  • 重點(diǎn):DecorView只是給狀態(tài)欄和導(dǎo)航欄預(yù)留位置改抡,俗稱背景矢炼,我們可以操作背景,但不能操作內(nèi)容阿纤。真正的內(nèi)容句灌,比如電池圖標(biāo)、運(yùn)營(yíng)商圖標(biāo)等是靠系統(tǒng)填充上去的欠拾。

再用圖表示狀態(tài)欄胰锌、導(dǎo)航欄添加流程:

image.png

ViewRootImpl相關(guān)請(qǐng)查看:Android Activity創(chuàng)建到View的顯示過(guò)程

狀態(tài)欄/導(dǎo)航欄 如何確定位置呢?

    public static final ColorViewAttributes STATUS_BAR_COLOR_VIEW_ATTRIBUTES =
            new ColorViewAttributes(SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
                    Gravity.TOP, Gravity.LEFT, Gravity.RIGHT,
                    Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME,
                    com.android.internal.R.id.statusBarBackground,
                    FLAG_FULLSCREEN);

    public static final ColorViewAttributes NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES =
            new ColorViewAttributes(
                    SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
                    Gravity.BOTTOM, Gravity.RIGHT, Gravity.LEFT,
                    Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
                    com.android.internal.R.id.navigationBarBackground,
                    0 /* hideWindowFlag */);

預(yù)先設(shè)置屬性清蚀,在updateColorViewInt(xx)設(shè)置View的Gravity匕荸。
導(dǎo)航欄:Gravity.BOTTOM
狀態(tài)欄:Gravity.TOP
這樣爹谭,導(dǎo)航欄和狀態(tài)欄在DecorView里的位置確定了枷邪。

DecorView子View位置與大小的確定

DecorView三個(gè)直接子View添加流程已經(jīng)確定,通過(guò)Layout Inspector看看其大小與位置:


image.png

從上圖兩個(gè)標(biāo)紅的矩形框分析:
LinearLayout 上邊界是頂?shù)狡聊唬逻吔绲呐c導(dǎo)航欄的頂部平齊东揣,而狀態(tài)欄是蓋在LinearLayout上的践惑,這也就是為什么我們可以設(shè)置沉浸式狀態(tài)欄的原因。
ContentFrameLayout包含了內(nèi)容區(qū)域嘶卧,ContentFrameLayout上邊界與標(biāo)題欄底部對(duì)齊尔觉,下邊界充滿父控件。
來(lái)看看代碼里如何確定LinearLayout和FrameLayout位置:

#View.java
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if ((mPrivateFlags3 & PFLAG3_FITTING_SYSTEM_WINDOWS) == 0) {
            //fitSystemWindows(xx)里面調(diào)用fitSystemWindowsInt(xx)
            if (fitSystemWindows(insets.getSystemWindowInsetsAsRect())) {
                return insets.consumeSystemWindowInsets();
            }
        } else {
            if (fitSystemWindowsInt(insets.getSystemWindowInsetsAsRect())) {
                return insets.consumeSystemWindowInsets();
            }
        }
        return insets;
    }

    private boolean fitSystemWindowsInt(Rect insets) {
        //對(duì)應(yīng)屬性android:fitsSystemWindows="true"
        if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) {
            mUserPaddingStart = UNDEFINED_PADDING;
            mUserPaddingEnd = UNDEFINED_PADDING;
            Rect localInsets = sThreadLocal.get();
            if (localInsets == null) {
                localInsets = new Rect();
                sThreadLocal.set(localInsets);
            }
            boolean res = computeFitSystemWindows(insets, localInsets);
            mUserPaddingLeftInitial = localInsets.left;
            mUserPaddingRightInitial = localInsets.right;
            //最終根據(jù)insets來(lái)設(shè)定該View的padding
            //設(shè)置padding芥吟,這里是設(shè)置paddingTop
            internalSetPadding(localInsets.left, localInsets.top,
                    localInsets.right, localInsets.bottom);
            return res;
        }
        return false;
    }

LinearLayout設(shè)置了android:fitsSystemWindows="true"侦铜,當(dāng)狀態(tài)欄展示的時(shí)候,需要將LinearLayout設(shè)置為適配狀態(tài)欄钟鸵,此處設(shè)置paddingTop="狀態(tài)欄高度"
加上之前設(shè)置的marginBottom="導(dǎo)航欄高度”钉稍,這就確定了LinearLayout位置。

ContentFrameLayout父控件是ActionBarOverlayLayout棺耍,因此它的位置受父控件控制贡未,ActionBarOverlayLayout計(jì)算標(biāo)題欄占的位置,而后設(shè)置ContentFrameLayout marginTop屬性蒙袍。

針對(duì)上面的布局俊卤,對(duì)應(yīng)的用圖說(shuō)話:


image.png

常見(jiàn)的獲取DecorView各個(gè)區(qū)塊大小的方法

既然知道了DecorView各個(gè)子View的布局,當(dāng)然就有相應(yīng)的方法獲取其大小害幅。

DecorView的尺寸

只要能獲取到DecorView對(duì)象消恍,一切都不在話下。
常見(jiàn)的通過(guò)Activity或者View獲冉孟蕖:
Activity:

getWindow().getDecorView()

View:

getRootView()

導(dǎo)航欄/狀態(tài)欄尺寸:

導(dǎo)航欄/狀態(tài)欄高度是由系統(tǒng)確定的哺哼,固化在資源字段里:

    public static int getStatusBarHeight(Context context) {
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        return context.getResources().getDimensionPixelSize(resourceId);
    }
    public static int getNavigationBarHeight(Context context) {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        int height = resources.getDimensionPixelSize(resourceId);
        return height;
    }

總結(jié)

兩篇文章分析了DecorView創(chuàng)建到展示一些布局細(xì)節(jié)。了解了DecorView的構(gòu)成叼风,我們做出一些效果更得心應(yīng)手取董,如:狀態(tài)欄沉浸/隱藏、Activity側(cè)滑關(guān)閉无宿、自定義通用標(biāo)題欄等茵汰。
注:以上關(guān)于DecorView、subDecor孽鸡、標(biāo)題欄蹂午、布局文件和區(qū)塊尺寸的選擇是基于當(dāng)前的demo的”蚣睿可能你所使用的主題豆胸、設(shè)置的屬性和本文不同導(dǎo)致布局效果差異,請(qǐng)注意甄別巷疼。
源碼基于:Android 10.0

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晚胡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌估盘,老刑警劉巖瓷患,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異遣妥,居然都是意外死亡擅编,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門箫踩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)爱态,“玉大人,你說(shuō)我怎么就攤上這事境钟≈辏” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵吱韭,是天一觀的道長(zhǎng)吆豹。 經(jīng)常有香客問(wèn)我,道長(zhǎng)理盆,這世上最難降的妖魔是什么痘煤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮猿规,結(jié)果婚禮上衷快,老公的妹妹穿的比我還像新娘。我一直安慰自己姨俩,他們只是感情好蘸拔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著环葵,像睡著了一般调窍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上张遭,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天邓萨,我揣著相機(jī)與錄音,去河邊找鬼菊卷。 笑死缔恳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洁闰。 我是一名探鬼主播歉甚,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼扑眉!你這毒婦竟也來(lái)了纸泄?” 一聲冷哼從身側(cè)響起雅镊,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刃滓,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體耸弄,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咧虎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了计呈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砰诵。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖捌显,靈堂內(nèi)的尸體忽然破棺而出茁彭,到底是詐尸還是另有隱情,我是刑警寧澤扶歪,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布理肺,位于F島的核電站,受9級(jí)特大地震影響善镰,放射性物質(zhì)發(fā)生泄漏妹萨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一炫欺、第九天 我趴在偏房一處隱蔽的房頂上張望乎完。 院中可真熱鬧,春花似錦品洛、人聲如沸树姨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)帽揪。三九已至,卻和暖如春辅斟,著一層夾襖步出監(jiān)牢的瞬間台丛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工砾肺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挽霉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓变汪,卻偏偏與公主長(zhǎng)得像侠坎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子裙盾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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