ConstraintLayout 的使用

ConstraintLayout 是在 2016 年 Google 大會上推出的一個新的布局控件,眾所周知,ConstraintLayout 有兩個優勢:使用 ConstraintLayout 編寫布局性能更高,使用 ConstraintLayout 可以通過拖拽的形式更方便地編寫布局文件。之前一直知道這個布局控件,但是一直沒有詳細地學習過,最近學習了它的使用,現在簡單記錄一下。

本文主要分為以下幾個部分:


catalog.png

1. 背景介紹

在面試的時候經常會被問到有沒有做過布局優化,都通過什么方式優化布局界面的?優化布局界面其中一種方式就是通過 ConstraintLayout 降低布局層級,從而避免過度測量和繪制。本篇文章重點講解 ConstraintLayout 的用法,關于 ConstraintLayout 性能方面的優勢,可以參考這篇文章:解析 ConstraintLayout 的性能優勢。

通過可視化拖拽的方式編寫 ConstraintLayout 布局界面,個人是不太推崇的,雖然它確實很方便,但是即使通過可視化拖拽的方式編寫布局之后,還是需要看懂 xml 文件中關于 ConstraintLayout 的屬性,才可以更靈活的修改布局界面,所以本文主要講解通過 xml 屬性的方式編寫 ConstraintLayout 布局界面,關于可視化拖拽的方式編寫 ConstraintLayout 布局界面,可以參考郭霖寫的這篇博客: Android 新特性介紹,ConstraintLayout 完全解析

好了,上面介紹了 ConstraintLayout 的兩個優點,下面開始進入本文的正題,通過 xml 布局屬性的方式編寫 ConstraintLayout 布局。使用之前,需要在 build.gradle 文件中添加對 ConstraintLayout 的依賴:

dependencies {
    ...
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    ...
}

2. 詳細使用

本節主要分為 7 點介紹 ConstraintLayout 的詳細使用,那就開始吧~

2.1 相對位置

ConstraintLayout 和 RelativeLayout 是非常類似的布局控件,它們之間最大的相似之處在于都可以編寫一個控件相對于其他控件或父控件的相對位置,比如下面這個樣式的布局既可以通過
RelativeLayout 實現,也可以通過 ConstraintLayout 實現


relativepositioning.png

通過 ConstraintLayout 實現的代碼如下所示:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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"
    tools:context="com.lijiankun24.constraintlayoutpractice.RelativePositionActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:title="@string/relative_positioning"
        app:titleTextColor="@android:color/white"/>

    <TextView
        android:id="@+id/tv_a"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:background="@color/colorPrimary"
        android:padding="30dp"
        android:text="A"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/tv_b"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>

    <TextView
        android:id="@+id/tv_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:background="@color/colorPrimary"
        android:padding="30dp"
        android:text="B"
        app:layout_constraintLeft_toRightOf="@+id/tv_a"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>
</android.support.constraint.ConstraintLayout>

通過上面的代碼,可以看到幾個陌生的 xml 屬性,它們都是 ConstraintLayout 的 xml 屬性,比如:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    ...
    >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        ...
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/tv_a"
        ...
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/tv_b"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>

    <TextView
        android:id="@+id/tv_b"
        ...
        app:layout_constraintLeft_toRightOf="@+id/tv_a"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>
</android.support.constraint.ConstraintLayout>

通過屬性的名字就可以猜測出它們大概的意思,比如:

  • app:layout_constraintLeft_toLeftOf 是指該控件的左邊緣和某個控件的左邊緣對齊
  • app:layout_constraintRight_toRightOf 是指該控件的右邊緣和某個控件的右邊緣對齊
  • app:layout_constraintTop_toBottomOf 是指該控件的上邊緣和某個控件的下邊緣對齊

依次類推,同樣含義的屬性還有:

  • layout_constraintLeft_toLeftOf
  • layout_constraintLeft_toRightOf
  • layout_constraintRight_toLeftOf
  • layout_constraintRight_toRightOf
  • layout_constraintTop_toTopOf
  • layout_constraintTop_toBottomOf
  • layout_constraintBottom_toTopOf
  • layout_constraintBottom_toBottomOf
  • layout_constraintStart_toEndOf
  • layout_constraintStart_toStartOf
  • layout_constraintEnd_toStartOf
  • layout_constraintEnd_toEndOf
  • layout_constraintBaseline_toBaselineOf

上述屬性的屬性值可以是某個控件的 id,也可以是 parent,比如:

app:layout_constraintLeft_toRightOf="@+id/tv_a"

app:layout_constraintRight_toRightOf="parent"

對于相對位置,官方給出的示意圖如下所示:


relativepositioning1.png

2.2 邊距(Margins)

假如現在有如下這樣一個界面:TextViewA 上邊距離 Toolbar 30dp,在屏幕最左邊,TextViewB 上邊距離 Toolbar 30dp,左邊距離 TextView A 也是 30dp,該如何編寫布局文件呢?


margin.png

該布局 xml 關鍵代碼如下所示:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    ...
    >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        ...
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/tv_a"
        ...
        android:layout_marginTop="30dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/tv_b"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>

    <TextView
        android:id="@+id/tv_b"
        ...
        android:layout_marginLeft="30dp"
        android:layout_marginTop="30dp"
        app:layout_constraintLeft_toRightOf="@+id/tv_a"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>
</android.support.constraint.ConstraintLayout>

在 ConstraintLayout 布局中,下面幾個 Margin 相關的屬性依然是有效的

  • android:layout_marginStart
  • android:layout_marginEnd
  • android:layout_marginLeft
  • android:layout_marginTop
  • android:layout_marginRight
  • android:layout_marginBottom

注意:在 ConstraintLayout 中,上述屬性值只可以是正數或者0,不可以是負數。

假如現在有這樣的一個需求,當 TextViewA 顯示的時候,TextViewB 距離左邊是 20dp;當 TextViewA 可見性為 Gone 的時候,TextViewB 距離左邊是 30dp,使用 ConstraintLayout 可以很容易的實現這樣的需求。

在 ConstraintLayout 中如下這些邊距屬性就是當依據的控件變為 Gone 的時候就會生效

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

2.3 居中顯示

假如說有如下圖所示的一個界面,TextViewA 在布局的正中間,如果用 RelativeLayout 和 LinearLayout 實現是很方便的,但是用 ConstraintLayout 怎么實現呢?


centerposition.png

其實也很簡單,代碼如下:

<android.support.constraint.ConstraintLayout
    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"
    tools:context="com.lijiankun24.constraintlayoutpractice.RelativePositionActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:title="@string/centering_positioning"
        app:titleTextColor="@android:color/white"/>

    <TextView
        android:id="@+id/tv_a"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:paddingBottom="10dp"
        android:paddingTop="10dp"
        android:text="A"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>
</android.support.constraint.ConstraintLayout>

在 ConstraintLayout 中并不像 LinearLayout 和 RelativeLayout 是通過 android:gravity="center"android:layout_gravity="center"android:layout_centerVertical="true"android:layout_centerHorizontal="true" 設置居中位置的,而是通過 app:layout_constraintBottom_toBottomOfapp:layout_constraintLeft_toLeftOfapp:layout_constraintRight_toRightOfapp:layout_constraintTop_toBottomOf 設置該控件上下左右分別依附于指定的控件即可。

在 ConstraintLayout 中有一個非常重要的概念 ---- constraint(約束):當控件有自己的大小時,例如:wrap_content 和具體的數值時,我們為控件添加的都是 constraint (約束),這個約束有點像橡皮筋一樣會有一個拉力拉著控件,但是并不會改變控件的大小。

例如上例,在居中顯示中,TextViewA 寬度為 100dp,左邊有 app:layout_constraintLeft_toLeftOf="parent" 約束,右邊有 app:layout_constraintRight_toRightOf="parent" 約束,左邊和右邊分別有一個同樣大小的力拉著 TextViewA 控件,所以 TextViewA 會水平居中,豎直方向也是一樣的。

如果想讓上述例子中的 TextViewA 水平方向撐滿整個父控件,即如下圖所示,那該怎么做呢?


centerposition1.png

首先我們想到的是使用 android:layout_width="match_parent" 實現,這樣設置之后確實也會實現這樣的效果,但是查看 ConstraintLayout 的官方文檔發現,在 ConstraintLayout 中 match_parent 已經被 match_constraint 所取代,所以使用 android:layout_width="0dp" 更為合適(在 xml 中并沒有 match_constraint 這個屬性值,0dp 即代碼 match_constraint 值)。

Bias屬性

可以在上下和左右分別有約束的時候加上偏移率,屬性如下所示:

app:layout_constraintHorizontal_bias="0.1"
app:layout_constraintVertical_bias="0.8"
  • layout_constraintHorizontal_bias 取值范圍是[0.0 ~ 1.0],從左向右
  • layout_constraintVertical_bias 取值范圍是[0.0 ~ 1.0],從上到下
    centerposition2.png

2.4 可見性對布局的影響

在 2.1 節中提到過幾個特殊的屬性:

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

這些屬性是配合著 layout_marginStart 等屬性使用的,當控件的約束所依附的 target 控件的 visibility 不為 GONE 的時候,layout_marginStart 等屬性起作用,當 target 控件的 visibility 為 GONE 的時候,layout_goneMarginStart 屬性起作用

2.5 尺寸約束

ConstraintLayout 的最小尺寸

當 ConstraintLayout 的寬度或者高度為 wrap_content 時,可以通過如下屬性為 ConstraintLayout 設置最小尺寸或最大尺寸

  • android:minWidth:最小寬度
  • android:minHeight:最小高度
  • android:maxWidth:最大寬度
  • android:maxHeight:最大高度

控件的尺寸約束

ConstraintLayout 中,設置控件的大小總共有三種方式,分別是:

  • 一個具體的屬性值,比如:123dp 或者一個 Dimension 引用
  • 使用 wrap_content,根據自身大小決定
  • 0dpmatch_constraint

控件按寬高比設置大小

ConstraintLayout 中,其中的控件可以按照寬高比設置其大小,前提是控件的寬或者高的尺寸至少有一個是 0dp,然后通過 layout_constraintDimensionRatio 設置控件的寬高比,顯示出來的控件的寬和高即是設置的比例的大小,如下所示:

<!-- 此 Button 的寬和高相等-->
<Button
  android:layout_width="wrap_content"
  android:layout_height="0dp"
  app:layout_constraintDimensionRatio="1:1" />

在上面 xml 代碼中,Button 的寬度是一個特定值:wrap_content,高度是一個可變值:0dp,寬:高 = 1 :1,則高度也就是和寬度相同的值

通過 layout_constraintDimensionRatio 設置的參數可以是:

  • 一個浮點數,代表 寬/高 的比例
  • 也可以是上述例子中的形式:寬:高

當控件寬和高的值都是 0dp 時,也可以通過 layout_constraintDimensionRatio 設置寬和高的比例,比如:

<Button
  android:layout_width="0dp"
  android:layout_height="0dp"
  app:layout_constraintDimensionRatio="H,16:9"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintTop_toTopOf="parent"/>

在上面 xml 代碼中,Button 的寬是可變值:0dp,高也是可變值:0dp,高:寬 = 16:9,但是 Button 有上下兩個約束:高頂到父控件的上邊緣,底頂到父控件的下邊緣,這樣 Button 的高度就固定了,再通過比例,即可得到寬 = 高 * 9/16.

2.5 鏈(Chains)

在 ConstraintLayout 中有一個非常重要的概念:鏈(Chains)

那什么才是鏈呢?在下圖所示的界面中即存在一個鏈:


chains.png

上圖中 TextViewA、TextViewB 和 TextViewC 形成了一個鏈,上圖對應的 xml 代碼是:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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"
    tools:context="com.lijiankun24.constraintlayoutpractice.RelativePositionActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:title="@string/chains"
        app:titleTextColor="@android:color/white"/>

    <TextView
        android:id="@+id/tv_a"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:background="@color/colorPrimary"
        android:padding="20dp"
        android:text="A"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/tv_b"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>

    <TextView
        android:id="@+id/tv_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:background="@color/colorPrimary"
        android:padding="20dp"
        android:text="B"
        app:layout_constraintLeft_toRightOf="@+id/tv_a"
        app:layout_constraintRight_toLeftOf="@+id/tv_c"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>


    <TextView
        android:id="@+id/tv_c"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:background="@color/colorPrimary"
        android:padding="20dp"
        android:text="C"
        app:layout_constraintLeft_toRightOf="@+id/tv_b"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"/>
</android.support.constraint.ConstraintLayout>

從代碼中可以看到形成鏈的三個控件有以下特點:

  • TextViewA 和 TextViewB 通過 app:layout_constraintRight_toLeftOf="@+id/tv_b"app:layout_constraintLeft_toRightOf="@+id/tv_a" 相互依賴
  • TextViewB 和 TextViewC 通過 app:layout_constraintRight_toLeftOf="@+id/tv_c"app:layout_constraintLeft_toRightOf="@+id/tv_b" 相互依賴

這樣便形成了一個鏈,在此鏈中最左邊的控件稱為鏈頭。同樣的也可以通過上下相互依賴形成上下的鏈,最上面的控件稱為鏈頭。

在鏈頭中通過 layout_constraintHorizontal_chainStylelayout_constraintVertical_chainStyle 可以設置鏈的樣式。
鏈的樣式總共有三種:

  • CHAIN_SPREAD:默認樣式
  • CHAIN_SPREAD_INSIDE
  • CHAIN_PACKED

用一張官方的圖解釋上面幾個屬性的含義,如下圖所示:


chainsStyle.png

這里需要強調下比重鏈(Weighted chain)樣式:在 CHAIN_SPREAD 樣式的鏈中,如果其中的控件的寬度或高度為 0dp,即可以通過 layout_constraintHorizontal_weightlayout_constraintVertical_weight 設置該控件在水平或者豎直方向的比例,類似于 LinearLayout 中的 weight 屬性的作用

2.6 Guideline

在 ConstraintLayout 中有一個特殊的輔助類:android.support.constraint.Guideline,主要用于輔助布局,可以把它看做是一個輔助線,但是不會繪制到界面上,有水平的和垂直的。

Guideline 有以下幾個屬性:

  • android:orientationverticalhorizontal,表示此 Guideline 是水平的還是垂直的
  • app:layout_constraintGuide_begin:表示 Guideline 的距離左邊或上邊的距離,根據方向決定是距離哪邊的
  • app:layout_constraintGuide_begin:表示 Guideline 的距離右邊或下邊的距離,根據方向決定是距離哪邊的
  • app:layout_constraintGuide_percent:表示 Guideline 距離左邊或上邊的百分比,根據方向決定是距離哪邊的

用一張效果圖展示 Guideline 的作用,一個 TextView 在中線的左邊 32dp 位置處,另一個 TextView 在中線右邊 32dp 處


guideline.png

上圖代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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"
    tools:context="com.lijiankun24.constraintlayoutpractice.VirtualHelpersActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:title="@string/virtual_helpers_objects"
        app:titleTextColor="@android:color/white"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="32dp"
        android:background="@android:color/holo_blue_light"
        android:text="@string/virtual_helpers_objects"
        android:textColor="@android:color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/guide_line"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        app:layout_constraintVertical_bias="0.502"/>

    <android.support.constraint.Guideline
        android:id="@+id/guide_line"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="32dp"
        android:background="@android:color/holo_blue_light"
        android:text="@string/virtual_helpers_objects"
        android:textColor="@android:color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/guide_line"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        app:layout_constraintVertical_bias="0.502"/>
</android.support.constraint.ConstraintLayout>

好啦,至此關于 ConstraintLayout 的使用就基本全部介紹完畢,是不是覺得很好用呢?那就趕快在項目中使用起來的!文中涉及的代碼都在這兒:ConstraintLayoutPractic


參考資料:

ConstraintLayout 官方文檔

ConstraintLayout 完全解析 快來優化你的布局吧 -- Hongyang

Android ConstraintLayout 約束布局 -- 打魚還是曬網 —— stone

ConstraintLayout約束布局使用教程難點理解 -- yueding

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,786評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,986評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,204評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,964評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,354評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,554評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,106評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,918評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,093評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,342評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,755評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,009評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,839評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,107評論 2 375

推薦閱讀更多精彩內容