CoordinatorLayout使用(二):Behavior流程 和 事件流

上一篇,我們大體理解了 Behavior簡單理解
具體代碼可以見 https://github.com/2954722256/use_little_demo
對應(yīng) coordinator 的 Module


簡單使用

知道大體作用以后,我們可以參考一下別人的文章
自己簡單搜索后挠羔,找一篇自己覺得很好的文章
例如:
http://www.reibang.com/p/a506ee4afecb
(大體講解Behavior以及對應(yīng)的反射注解實現(xiàn))
其中池户,有一個View一直在另一個View的下方
是通過自定義View熙揍,傳遞id來實現(xiàn)的

http://www.reibang.com/p/39fbc9f4f0c6
一些總結(jié)感覺寫得挺好
比如戳鹅,一些寫法今妄,一些分類
雖然沒有什么圖示


自己簡單實現(xiàn)

先寫對應(yīng)的Behavior
這里簡單一點菲盾,不用 自定義屬性颓影,傳遞id了
直接寫死對應(yīng)的 dependencyView
只需要把這個View的Y值, 設(shè)置為 dependencyView的Y值 + dependencyView的高度 即可

DodoBelowBehavior 類
package com.aohuan.dodo.coordinator.utils;

import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;

import com.aohuan.dodo.coordinator.view.DodoMoveView;

/**
 * Created by dodo on 2016/11/1.
 * qq: 2390183798
 *
 *
 * 在Main View 下方
 *      原理也簡單懒鉴, 只要是 Main View 為 DodoMoveView诡挂,  就設(shè)置 一起動的View的Y值為 自己的Y值 + MainView的Height
 */
public class DodoBelowBehavior extends CoordinatorLayout.Behavior<View> {

    public DodoBelowBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        child.setY(dependency.getY()+dependency.getHeight());
        return true;
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return dependency instanceof DodoMoveView;
    }

}

對應(yīng)的layout為:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.aohuan.dodo.coordinator.view.DodoMoveView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#666666"
            android:gravity="center"
            android:layout_gravity="top|right"
            android:text="Main" />

        <Button
            android:id="@+id/btn"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#888888"
            android:text="  Dodo Below  "
            app:layout_behavior="com.aohuan.dodo.coordinator.utils.DodoBelowBehavior" />

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

</LinearLayout>

layout中度帮,將需要上下關(guān)聯(lián)的View放在一個 CoordinatorLayout 中
在給跟著動的View設(shè)置Behavior即可

我們看一下效果:


簡單總結(jié)

對應(yīng)的總結(jié)蒋畜,參考文章:
http://www.reibang.com/p/39fbc9f4f0c6

前提: 上面只是簡單使用了一部分爵政,總結(jié)后前计,后續(xù)文章再一起探索

markdown 的二級和代碼解析居砖,有一些沖突间螟, 和之前wiki排版差不多赞警,由于不重要验辞,所以自己不花時間去整理了抄课, 有時間找到解決方法后唱星,再做修改


自定義Behavior的通用流程
通常分為:

  • 重寫構(gòu)造方法
  • 綁定到View
  • 判斷依賴對象

事件流
通常分為:(為了好記,自己名字可能不太一樣)

  • 觸摸事件
  • 計算和布局事件
  • CoordinatorLayout關(guān)聯(lián)事件
  • 嵌套滑動事件

自定義Behavior的通用流程

對應(yīng)的Behavior的路程大體為:

  • 1. 重寫構(gòu)造方法

public class CustomBehavior extends CoordinatorLayout.Behavior {

public CustomBehavior(Context context, AttributeSet attrs) {
    super(context, attrs);
}

}


- **2. 綁定到View**
  - 一定要重寫這個構(gòu)造方法跟磨,因為當(dāng)你在XML中設(shè)置該Behavior時间聊, 
  - 在 CoordinatorLayout中會反射調(diào)用該方法,并生成該 Behavior 實例抵拘。
  - **綁定的方法有三種:**
    - 在 XML 文件中哎榴,設(shè)置任意 View 的屬性
      - ```
app:layout_behavior="你的Behavior的包路徑和類名"
- 或者在代碼中:
  - ```

(CoordinatorLayout.LayoutParams)child.getLayoutParams().setBehavior();

    - 或者在你的自定義View類上添加@DefaultBehavior(你的Behavior.class)
      - ```
@DefaultBehavior(CustomBehavior.class)
public class CustomView extends View {}
  • 3. 判斷依賴對象
    • 過程:
      • 當(dāng) CoordinatorLayout 收到某個 view 的變化或者嵌套滑動事件時
      • CoordinatorLayout就會嘗試把事件下發(fā)給Behavior
      • 綁定了該 Behavior 的 view 就會對事件做出響應(yīng)
    • 判斷關(guān)系的幾種方式
      • 根據(jù)id

public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
·   return dependency.getId() == R.id.xxx;
}
- **根據(jù)類型**
  - 
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
    ·   return dependency instanceof CustomView;
}
- **自定義View的id傳遞**
  - 自定義屬性
    - 
<declare-styleable name="Follow">
    <attr name="target" format="reference"/>
</declare-styleable>
  - layout中傳遞id
    - 
<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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">
    <View
        android:id="@+id/first"
        android:layout_width="match_parent"
        android:layout_height="128dp"
        android:background="@android:color/holo_blue_light"/>
    <View
        android:id="@+id/second"
        android:layout_width="match_parent"
        android:layout_height="128dp"
        app:layout_behavior=".FollowBehavior"
        app:target="@id/first"
        android:background="@android:color/holo_green_light"/>
</android.support.design.widget.CoordinatorLayout>
  - Behavior中獲取對象
    - 
public class FollowBehavior extends CoordinatorLayout.Behavior {
    private int targetId;
    public FollowBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Follow);
        for (int i = 0; i < a.getIndexCount(); i++) {
            int attr = a.getIndex(i);
            if(a.getIndex(i) == R.styleable.Follow_target){
                targetId = a.getResourceId(attr, -1);
            }
        }
        a.recycle();
    }
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        return true;
    }
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return dependency.getId() == targetId;
    }
}

事件流

為了便于記憶,對應(yīng)的事件僵蛛,大體分為下面幾種

  • 觸摸事件
    • 我們知道View的事件分發(fā)中有這2個方法:(dispatchEvent先忽略)

public boolean onInterceptTouchEvent(MotionEvent ev)
public boolean onTouchEvent(MotionEvent ev)
  • CoordinatorLayout 會嘗試調(diào)用其 Child View 擁有的 Behavior 中的同名方法

public boolean onInterceptTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev)
public boolean onTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev)
  • 如果 Behavior 對觸摸事件進行了攔截尚蝌,就不會再分發(fā)到 Child View 自身擁有的觸摸事件中
    • 這就意味著:在不知道具體View的情況下,就可以重寫它的觸摸事件
    • onTouch事件是CoordinatorLayout分發(fā)下來的充尉,所以這里的onTouchEvent并不是我們控件自己的onTouch事件驼壶,也就是說,你假如手指不在我們的控件上滑動喉酌,也會觸發(fā)onTouchEvent
    • 需要在onTouchEvent 方法中的 MotionEvent.ACTION_DOWN 下添加:

ox = ev.getX();
oy = ev.getY();
if (oy < child.getTop() || oy > child.getBottom() || ox < child.getLeft() || ox > child.getRight()) { 
·   return true;
}
  - 手勢過濾热凹,以后自己再單獨找資料學(xué)習(xí)
  • 計算和布局事件
    • View的計算和布局有這2個方法

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
protected void onLayout(boolean changed, int l, int t, int r, int b)
  • CoordinatorLayout 也會嘗試調(diào)用其 Child View 擁有的 Behavior 中對應(yīng)的同名方法

public boolean onMeasureChild(CoordinatorLayout parent, V child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)
public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection)  
- 同樣地泵喘,CoordinatorLayout 會優(yōu)先處理 Behavior 中所重寫的布局事件
  • CoordinatorLayout關(guān)聯(lián)事件
    • 這個上面也用過部分類似的,應(yīng)該會有點印象
    • 這個關(guān)聯(lián)事件 是指 View 的位置般妙、尺寸發(fā)生了變化
    • CoordinatorLayoutonDraw 方法中纪铺,會遍歷全部的 Child View 嘗試尋找是否有相互關(guān)聯(lián)的對象
    • 確定是否關(guān)聯(lián)的方式有兩種:
      • 1. Behavior中定義
        • 通過 Behavior 的 layoutDependsOn 方法來判斷是否有依賴關(guān)系
          • 這個前面的例子中,已經(jīng)用過很多次了
            • 判斷是dependency是否是當(dāng)前behavior需要的對象
            • parent CoordinatorLayout
            • child 該Behavior對應(yīng)的那個View
            • dependency dependency 要檢查的View
            • return true 依賴, false 不依賴
          • 大體常見的3種方式碟渺,可以參考前面的說明
        • 如果有就繼續(xù)調(diào)用 onDependentViewChanged
          • 這個上面也詳細(xì)說明過
          • 當(dāng)改變dependency的尺寸或者位置時被調(diào)用
            • parent CoordinatorLayout
            • child 該Behavior對應(yīng)的那個View
            • dependency child依賴dependency
            • return true 處理了, false 沒處理
        • 在layoutDependsOn返回true的基礎(chǔ)上之后鲜锚,onDependentViewRemoved通知dependency被移除了
          • parent CoordinatorLayout
          • child 該Behavior對應(yīng)的那個View
          • dependency child依賴dependency
      • 2. XML中設(shè)置屬性
        • 通過 XML 中設(shè)置的 layout_anchor
        • 關(guān)聯(lián)設(shè)置 layout_anchor 的 Child View 與 layout_anchor
        • dependency View隨后調(diào)用 offsetChildToAnchor(child, layoutDirection)
        • 其實就是調(diào)整兩者的位置,讓它們可以一起變化
app:layout_anchor="@id/dependencyView.id"
  • 嵌套滑動事件
    • 大體分為 子控件 和 父控件苫拍, 也就是 被觸發(fā)的 和 觸發(fā)的

      • 具體大致就是 NestedScrollingChild 芜繁, NestedScrollingParentBehavior子類
      • 一些理解绒极,可以參考 鴻洋的一篇博客:
      • 自己的理解:
        • 實現(xiàn)NestedScrollingChild接口骏令,獲得事件,準(zhǔn)備傳遞給 NestedScrollingParent
        • 實現(xiàn)NestedScrollingParent接口垄提,獲取傳遞的事件榔袋,消費或者傳遞給Behavior子類消費
        • 繼承抽象類Behavior,獲得事件铡俐,進行消費凰兑。完成對應(yīng)View動作
    • 1. 實現(xiàn)NestedScrollingChild

      • 如果一個View想向外界傳遞滑動事件,即通知 NestedScrollingParent 审丘,就必須實現(xiàn)此接口
      • 而 Child 與 Parent 的具體交互邏輯吏够, NestedScrollingChildHelper 輔助類基本已經(jīng)幫我們封裝好了,所以我們只需要調(diào)用對應(yīng)的方法即可
      • NestedScrollingChild接口的一般實現(xiàn):
public class CustomNestedScrollingChildView extends View implements NestedScrollingChild {
    private NestedScrollingChildHelper mChildHelper = new NestedScrollingChildHelper(this);
    /**
     * 設(shè)置當(dāng)前View能否滑動
     * @param enabled
     */
    @Override
    public void setNestedScrollingEnabled(boolean enabled) {
        mChildHelper.setNestedScrollingEnabled(enabled);
    }
    /**
     * 判斷當(dāng)前View能否滑動
     * @return
     */
    @Override
    public boolean isNestedScrollingEnabled() {
        return mChildHelper.isNestedScrollingEnabled();
    }
    /**
     * 啟動嵌套滑動事件流
     * 1. 尋找可以接收 NestedScroll 事件的 parent view滩报,即實現(xiàn)了 NestedScrollingParent 接口的 ViewGroup
     * 2. 通知該 parent view锅知,現(xiàn)在我要把滑動的參數(shù)傳遞給你
     * @param axes
     * @return
     */
    @Override
    public boolean startNestedScroll(int axes) {
        return mChildHelper.startNestedScroll(axes);
    }
    /**
     * 停止嵌套滑動事件流
     */
    @Override
    public void stopNestedScroll() {
        mChildHelper.stopNestedScroll();
    }
    /**
     * 是否存在接收 NestedScroll 事件的 parent view
     * @return
     */
    @Override
    public boolean hasNestedScrollingParent() {
        return mChildHelper.hasNestedScrollingParent();
    }
    /**
     * 在滑動之后,向父view匯報滾動情況露泊,包括child view消費的部分和child view沒有消費的部分喉镰。
     * @param dxConsumed x方向已消費的滑動距離
     * @param dyConsumed y方向已消費的滑動距離
     * @param dxUnconsumed x方向未消費的滑動距離
     * @param dyUnconsumed y方向未消費的滑動距離
     * @param offsetInWindow 如果parent view滑動導(dǎo)致child view的窗口發(fā)生了變化(child View的位置發(fā)生了變化)
     *                       該參數(shù)返回x(offsetInWindow[0]) y(offsetInWindow[1])方向的變化
     *                       如果你記錄了手指最后的位置,需要根據(jù)參數(shù)offsetInWindow計算偏移量惭笑,
     *                       才能保證下一次的touch事件的計算是正確的侣姆。
     * @return 如果parent view接受了它的滾動參數(shù),進行了部分消費沉噩,則這個函數(shù)返回true捺宗,否則為false。
     */
    @Override
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
                                        int dyUnconsumed, int[] offsetInWindow) {
        return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,
                offsetInWindow);
    }
    /**
     * 在滑動之前川蒙,先問一下 parent view 是否需要滑動蚜厉,
     * 即child view的onInterceptTouchEvent或onTouchEvent方法中調(diào)用。
     * 1. 如果parent view滑動了一定距離畜眨,你需要重新計算一下parent view滑動后剩下給你的滑動距離剩余量昼牛,
     *      然后自己進行剩余的滑動术瓮。
     * 2. 該方法的第三第四個參數(shù)返回parent view消費掉的滑動距離和child view的窗口偏移量,
     *      如果你記錄了手指最后的位置贰健,需要根據(jù)第四個參數(shù)offsetInWindow計算偏移量胞四,
     *      才能保證下一次的touch事件的計算是正確的。
     * @param dx x方向的滑動距離
     * @param dy y方向的滑動距離
     * @param consumed 如果不是null, 則告訴child view現(xiàn)在parent view滑動的情況伶椿,
     *                 consumed[0]parent view告訴child view水平方向滑動的距離(dx)
     *                 consumed[1]parent view告訴child view垂直方向滑動的距離(dy)
     * @param offsetInWindow 可選 length=2 的數(shù)組辜伟,
     *                       如果parent view滑動導(dǎo)致child View的窗口發(fā)生了變化(子View的位置發(fā)生了變化)
     *                       該參數(shù)返回x(offsetInWindow[0]) y(offsetInWindow[1])方向的變化
     *                       如果你記錄了手指最后的位置,需要根據(jù)參數(shù)offsetInWindow計算偏移量脊另,
     *                       才能保證下一次的touch事件的計算是正確的导狡。
     * @return 如果parent view對滑動距離進行了部分消費,則這個函數(shù)返回true偎痛,否則為false旱捧。
     */
    @Override
    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
        return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
    }
    /**
     * 在嵌套滑動的child view快速滑動之后再調(diào)用該函數(shù)向parent view匯報快速滑動情況。
     * @param velocityX 水平方向的速度
     * @param velocityY 垂直方向的速度
     * @param consumed true 表示child view快速滑動了, false 表示child view沒有快速滑動
     * @return true 表示parent view快速滑動了, false 表示parent view沒有快速滑動
     */
    @Override
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
        return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
    }
    /**
     * 在嵌套滑動的child view快速滑動之前告訴parent view快速滑動的情況看彼。
     * @param velocityX 水平方向的速度
     * @param velocityY 垂直方向的速度
     * @return true 表示parent view快速滑動了, false 表示parent view沒有快速滑動
     */
    @Override
    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
        return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
    }
}
  • 2. 實現(xiàn)NestedScrollingParent
    • 如果一個View Group想接收來自 NestedScrollingChild 的滑動事件廊佩,就需要實現(xiàn)該接口囚聚。
    • 同樣有一個 NestedScrollingParentHelper 輔助類靖榕,幫我們封裝好了 parent viewchild view之間的具體交互邏輯。
    • NestedScrollingChild 主動發(fā)出滑動事件傳遞給 NestedScrollingParent顽铸,NestedScrollingParent 做出響應(yīng)
    • 之間的調(diào)用關(guān)系如下表所示:
Child View Parent View
startNestedScroll onStartNestedScroll茁计、onNestedScrollAccepted
dispatchNestedPreScroll onNestedPreScroll
dispatchNestedScroll onNestedScroll
stopNestedScroll onStopNestedScroll
dispatchNestedFling onNestedFling
dispatchNestedPreFling onNestedPreFling
  • 3. Behavior子類獲得事件,對應(yīng)View變化
    • Parent View 自身并不會消費滑動距離谓松,都是傳遞給 Behavior
    • 擁有這個 BehaviorChild View 才是真正消費滑動距離的實例
    • Behavior 擁有與 NestedScrollingParent 接口完全同名的方法星压。在每一個 NestedScrollingParent 的方法中都會調(diào)用 Behavior 中的同名方法
    • 特殊方法的說明:
      • public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes)
        • 開始嵌套滑動的時候被調(diào)用
        • 需要判斷滑動的方向是否是我們需要的
          • nestedScrollAxes == ViewCompat.SCROLL_AXIS_HORIZONTAL 表示是水平方向的滑動
          • nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL 表示是豎直方向的滑動
        • 對應(yīng)的返回值:
          • 返回 true 表示繼續(xù)接收后續(xù)的滑動事件,
          • 返回 false 表示不再接收后續(xù)滑動事件
      • public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)
        • 滑動中調(diào)用
        • 1 正在上滑: dyConsumed > 0 && dyUnconsumed == 0
        • 2 已經(jīng)到頂部了還在上滑: dyConsumed == 0 && dyUnconsumed > 0
        • 3 正在下滑: dyConsumed < 0 && dyUnconsumed == 0
        • 4 已經(jīng)打底部了還在下滑: dyConsumed == 0 && dyUnconsumed < 0
      • public boolean onNestedFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY, boolean consumed)
        • 快速滑動中調(diào)用

事件流總結(jié)

前面有寫鬼譬,通常分為:

  • 事件來自外部父view
    • 觸摸事件
      • BehavioronInterceptTouchEvent + onTouchEvent
    • 計算和布局事件
      • BehavioronMeasureChild + onLayoutChild
  • 事件來自內(nèi)部子view
    • CoordinatorLayout關(guān)聯(lián)事件
      • BehaviorlayoutDependsOn + onDependentViewChanged + onDependentViewRemoved
    • 嵌套滑動事件
      • BehavioronStartNestedScroll + onNestedScrollAccepted + onStopNestedScroll + onNestedScroll + onNestedPreScroll + onNestedFling + onNestedPreFling

其他參考


簡單回顧

最開始的demo和后面的流程關(guān)系不大
開始的demo大體也可以理解成:

  • 自己定義的View,相當(dāng)于NestedScrollingChild优质,獲得事件竣贪,傳遞給 NestedScrollingParent
  • CoordinatorLayout 實現(xiàn)NestedScrollingParent接口,獲取傳遞的事件巩螃,傳遞給Behavior子類消費
  • 自定義的Behavior繼承抽象類Behavior演怎,獲得事件,進行消費避乏。完成對應(yīng)View動作

這篇文章內(nèi)容很少爷耀,也很多
只有1個demo,但是總結(jié)的很多
其他的內(nèi)容拍皮,后續(xù)一起學(xué)習(xí)

具體代碼歹叮,可以見
https://github.com/2954722256/use_little_demo
對應(yīng) coordinator 的 Module

其他總結(jié)跑杭,后續(xù)的文章,接著參考分析咆耿,和大家一起學(xué)習(xí)艘蹋。


下一篇我們可以了解
NestedScrollView & 嵌套滑動事件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市票灰,隨后出現(xiàn)的幾起案子女阀,更是在濱河造成了極大的恐慌,老刑警劉巖屑迂,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浸策,死亡現(xiàn)場離奇詭異,居然都是意外死亡惹盼,警方通過查閱死者的電腦和手機庸汗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來手报,“玉大人蚯舱,你說我怎么就攤上這事⊙诟颍” “怎么了枉昏?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長揍鸟。 經(jīng)常有香客問我兄裂,道長,這世上最難降的妖魔是什么阳藻? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任晰奖,我火速辦了婚禮,結(jié)果婚禮上腥泥,老公的妹妹穿的比我還像新娘匾南。我一直安慰自己,他們只是感情好蛔外,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布蛆楞。 她就那樣靜靜地躺著,像睡著了一般冒萄。 火紅的嫁衣襯著肌膚如雪臊岸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天尊流,我揣著相機與錄音帅戒,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛逻住,可吹牛的內(nèi)容都是我干的钟哥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼瞎访,長吁一口氣:“原來是場噩夢啊……” “哼腻贰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起扒秸,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤播演,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后伴奥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體写烤,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年拾徙,在試婚紗的時候發(fā)現(xiàn)自己被綠了洲炊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡尼啡,死狀恐怖暂衡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崖瞭,我是刑警寧澤狂巢,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站读恃,受9級特大地震影響隧膘,放射性物質(zhì)發(fā)生泄漏代态。R本人自食惡果不足惜寺惫,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹦疑。 院中可真熱鬧西雀,春花似錦、人聲如沸歉摧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叁温。三九已至再悼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間膝但,已是汗流浹背冲九。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留跟束,地道東北人莺奸。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓丑孩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灭贷。 傳聞我的和親對象是個殘疾皇子温学,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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