Android 可分組的RecyclerViewAdapter

轉(zhuǎn)載請(qǐng)說(shuō)明出處:http://www.reibang.com/p/302d24db5423

今天給大家介紹的是一個(gè)可以實(shí)現(xiàn)數(shù)據(jù)分組顯示的RecyclerViewAdapter:GroupedRecyclerViewAdapter音五。它可以很方便的實(shí)現(xiàn)RecyclerView的分組顯示珍手,并且每個(gè)組都可以包含組頭寨躁、組尾和子項(xiàng)器联;可以方便實(shí)現(xiàn)多種Type類(lèi)型的列表谆奥,可以實(shí)現(xiàn)如QQ聯(lián)系人的列表一樣的列表展開(kāi)收起功能等哎榴。下面先讓我們看一下它所能夠?qū)崿F(xiàn)的一些效果:

分組的列表
不帶組尾的列表
不帶組頭的列表

子項(xiàng)為Grid的列表

子項(xiàng)為Grid的列表(各組子項(xiàng)的Span不同)

頭琼蚯、尾和子項(xiàng)都支持多種類(lèi)型的列表
多種子項(xiàng)類(lèi)型的列表

還可以很容易的實(shí)時(shí)列表的展開(kāi)收起效果:


可展開(kāi)收起的列表

以上展示的只是GroupedRecyclerViewAdapter能實(shí)現(xiàn)的一些常用效果蜕着,其實(shí)使用GroupedRecyclerViewAdapter還可以很容易的實(shí)現(xiàn)一些更加復(fù)雜的列表效果谋竖。在我的GroupedRecyclerViewAdapter項(xiàng)目的Demo中給出了上面幾種效果的實(shí)現(xiàn)例子,并且有詳細(xì)的注釋說(shuō)明承匣,有興趣的同學(xué)可以到我的GitHub下載源碼蓖乘。下面直接講解GroupedRecyclerViewAdapter的使用。

**1韧骗、引入依賴(lài) **
在Project的build.gradle在添加以下代碼

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

在Module的build.gradle在添加以下代碼

    compile 'com.github.donkingliang:GroupedRecyclerViewAdapter:1.3.0'

2嘉抒、繼承GroupedRecyclerViewAdapter

public class GroupedListAdapter extends GroupedRecyclerViewAdapter {
}

3、實(shí)現(xiàn)GroupedRecyclerViewAdapter里的方法
GroupedRecyclerViewAdapter是一個(gè)抽象類(lèi)袍暴,它提供了一系列需要子類(lèi)去實(shí)現(xiàn)的方法众眨。

    //返回組的數(shù)量
    public abstract int getGroupCount();

    //返回當(dāng)前組的子項(xiàng)數(shù)量
    public abstract int getChildrenCount(int groupPosition);

    //當(dāng)前組是否有頭部
    public abstract boolean hasHeader(int groupPosition);

    //當(dāng)前組是否有尾部
    public abstract boolean hasFooter(int groupPosition);

    //返回頭部的布局id。(如果hasHeader返回false容诬,這個(gè)方法不會(huì)執(zhí)行)
    public abstract int getHeaderLayout(int viewType);

    //返回尾部的布局id娩梨。(如果hasFooter返回false,這個(gè)方法不會(huì)執(zhí)行)
    public abstract int getFooterLayout(int viewType);

    //返回子項(xiàng)的布局id览徒。
    public abstract int getChildLayout(int viewType);

    //綁定頭部布局?jǐn)?shù)據(jù)狈定。(如果hasHeader返回false,這個(gè)方法不會(huì)執(zhí)行)
    public abstract void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition);

    //綁定尾部布局?jǐn)?shù)據(jù)。(如果hasFooter返回false纽什,這個(gè)方法不會(huì)執(zhí)行)
    public abstract void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition);

    //綁定子項(xiàng)布局?jǐn)?shù)據(jù)措嵌。
    public abstract void onBindChildViewHolder(BaseViewHolder holder,
                                               int groupPosition, int childPosition);

還可是重寫(xiě)GroupedRecyclerViewAdapter方法實(shí)現(xiàn)頭、尾和子項(xiàng)的多種類(lèi)型item芦缰。效果就像上面的第6張圖一樣企巢。

    //返回頭部的viewType。
    public int getHeaderViewType(int groupPosition);

    //返回尾部的viewType让蕾。
    public int getFooterViewType(int groupPosition) ;

    //返回子項(xiàng)的viewType浪规。
    public int getChildViewType(int groupPosition, int childPosition) ;

4、設(shè)置點(diǎn)擊事件的監(jiān)聽(tīng)
GroupedRecyclerViewAdapter提供了對(duì)列表的點(diǎn)擊事件的監(jiān)聽(tīng)方法探孝。

    //設(shè)置組頭點(diǎn)擊事件
    public void setOnHeaderClickListener(OnHeaderClickListener listener) {
        mOnHeaderClickListener = listener;
    }

    //設(shè)置組尾點(diǎn)擊事件
    public void setOnFooterClickListener(OnFooterClickListener listener) {
        mOnFooterClickListener = listener;
    }

    // 設(shè)置子項(xiàng)點(diǎn)擊事件
    public void setOnChildClickListener(OnChildClickListener listener) {
        mOnChildClickListener = listener;
    }

注意事項(xiàng):

1笋婿、對(duì)方法重寫(xiě)的注意。
如果我們直接繼承RecyclerView.Adapter去實(shí)現(xiàn)自己的Adapter時(shí)顿颅,一般會(huì)重寫(xiě)Adapter中的以下幾個(gè)方法:

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType);

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position);

public int getItemCount();

public int getItemViewType(int position);

但如果是使用GroupedRecyclerViewAdapter缸濒,就一定不能去重寫(xiě)這幾個(gè)方法,因?yàn)樵贕roupedRecyclerViewAdapter中已經(jīng)對(duì)這幾個(gè)方法做了實(shí)現(xiàn)粱腻,而且是對(duì)實(shí)現(xiàn)列表分組至關(guān)重要的庇配,如果子類(lèi)重寫(xiě)了這幾個(gè)方法,可能會(huì)破壞GroupedRecyclerViewAdapter的功能绍些。
從前面給出的GroupedRecyclerViewAdapter的方法我們可以看到讨永,這些方法其實(shí)就是對(duì)應(yīng)RecyclerView.Adapter的這4個(gè)方法的,所以我們直接使用GroupedRecyclerViewAdapter提供的方法即可遇革。
RecyclerView.Adapter中的

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType);

對(duì)應(yīng)GroupedRecyclerViewAdapter中的

    //返回頭部的布局id卿闹。(如果hasHeader返回false,這個(gè)方法不會(huì)執(zhí)行)
    public abstract int getHeaderLayout(int viewType);

    //返回尾部的布局id萝快。(如果hasFooter返回false锻霎,這個(gè)方法不會(huì)執(zhí)行)
    public abstract int getFooterLayout(int viewType);

    //返回子項(xiàng)的布局id。
    public abstract int getChildLayout(int viewType);

這里之所以返回的是布局id而不是ViewHolder 揪漩,是因?yàn)樵贕roupedRecyclerViewAdapter項(xiàng)目中已經(jīng)提供了一個(gè)通用的ViewHolder:BaseViewHolder旋恼。所以使用者只需要提供布局的id即可,不需要自己去實(shí)現(xiàn)ViewHolder奄容。

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(getLayoutId(mTempPosition, viewType), parent, false);
        return new BaseViewHolder(view);
    }

    private int getLayoutId(int position, int viewType) {
        int type = judgeType(position);
        if (type == TYPE_HEADER) {
            return getHeaderLayout(viewType);
        } else if (type == TYPE_FOOTER) {
            return getFooterLayout(viewType);
        } else if (type == TYPE_CHILD) {
            return getChildLayout(viewType);
        }
        return 0;
    }

RecyclerView.Adapter中的

    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position);

對(duì)應(yīng)GroupedRecyclerViewAdapter中的

    //綁定頭部布局?jǐn)?shù)據(jù)冰更。(如果hasHeader返回false,這個(gè)方法不會(huì)執(zhí)行)
    public abstract void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition);

    //綁定尾部布局?jǐn)?shù)據(jù)昂勒。(如果hasFooter返回false蜀细,這個(gè)方法不會(huì)執(zhí)行)
    public abstract void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition);

    //綁定子項(xiàng)布局?jǐn)?shù)據(jù)。
    public abstract void onBindChildViewHolder(BaseViewHolder holder,
                                               int groupPosition, int childPosition);

RecyclerView.Adapter中的

    public int getItemCount();

對(duì)應(yīng)GroupedRecyclerViewAdapter中的

    //返回組的數(shù)量
    public abstract int getGroupCount();

    //返回當(dāng)前組的子項(xiàng)數(shù)量
    public abstract int getChildrenCount(int groupPosition);

RecyclerView.Adapter中的

    public int getItemViewType(int position);

對(duì)應(yīng)GroupedRecyclerViewAdapter中的

    //返回頭部的viewType戈盈。
    public int getHeaderViewType(int groupPosition);

    //返回尾部的viewType奠衔。
    public int getFooterViewType(int groupPosition) ;

    //返回子項(xiàng)的viewType谆刨。
    public int getChildViewType(int groupPosition, int childPosition) ;

2、對(duì)列表操作的注意
RecyclerView.Adapter提供了一系列對(duì)列表進(jìn)行操作的方法归斤。如:

//更新操作
public final void notifyDataSetChanged();
public final void notifyItemChanged(int position);
public final void notifyItemChanged(int position, Object payload);
public final void notifyItemRangeChanged(int positionStart, int itemCount);
public final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload);

//插入操作
public final void notifyItemInserted(int position);
public final void notifyItemRangeInserted(int positionStart, int itemCount);

//刪除操作
public final void notifyItemRemoved(int position)
public final void notifyItemRangeRemoved(int positionStart, int itemCount);

在GroupedRecyclerViewAdapter不建議使用RecyclerView.Adapter的任何對(duì)列表的操作方法痊夭,因?yàn)檫@些方法都是基于列表的操作,它的position是相對(duì)于整個(gè)列表而言的脏里,而GroupedRecyclerViewAdapter是分組的列表她我,它對(duì)列表的操作應(yīng)該是基于組的。同時(shí)GroupedRecyclerViewAdapter使用了組結(jié)構(gòu)來(lái)維護(hù)整個(gè)列表的結(jié)構(gòu)迫横,使我們可以對(duì)列表進(jìn)行組的操作番舆,在列表發(fā)生變化時(shí)GroupedRecyclerViewAdapter需要及時(shí)對(duì)組結(jié)構(gòu)進(jìn)行調(diào)整,如果使用了RecyclerView.Adapter中的方法對(duì)列表進(jìn)行更新员淫,GroupedRecyclerViewAdapter可能因?yàn)闊o(wú)法及時(shí)調(diào)整組結(jié)構(gòu)而發(fā)生異常。所以在使用中應(yīng)該避免使用這些方法击敌。GroupedRecyclerViewAdapter同樣提供了一系列對(duì)列表進(jìn)行操作的方法介返,我們應(yīng)該使用GroupedRecyclerViewAdapter所提供的方法。

     //****** 刷新操作 *****//

    //通知數(shù)據(jù)列表刷新沃斤。對(duì)應(yīng) notifyDataSetChanged();
    public void notifyDataChanged();

    //通知一組數(shù)據(jù)刷新圣蝎,包括組頭,組尾和子項(xiàng)
    public void notifyGroupChanged(int groupPosition);

    //通知多組數(shù)據(jù)刷新,包括組頭,組尾和子項(xiàng)
    public void notifyGroupRangeChanged(int groupPosition, int count);

    // 通知組頭刷新
    public void notifyHeaderChanged(int groupPosition);

    // 通知組尾刷新
    public void notifyFooterChanged(int groupPosition);

    // 通知一組里的某個(gè)子項(xiàng)刷新
    public void notifyChildChanged(int groupPosition, int childPosition);

    // 通知一組里的多個(gè)子項(xiàng)刷新
    public void notifyChildRangeChanged(int groupPosition, int childPosition, int count);

    // 通知一組里的所有子項(xiàng)刷新
    public void notifyChildrenChanged(int groupPosition);

    //****** 刪除操作 *****//
    // 通知所有數(shù)據(jù)刪除
    public void notifyDataRemoved();

    // 通知一組數(shù)據(jù)刪除衡瓶,包括組頭,組尾和子項(xiàng)
    public void notifyGroupRemoved(int groupPosition);

    // 通知多組數(shù)據(jù)刪除徘公,包括組頭,組尾和子項(xiàng)
    public void notifyGroupRangeRemoved(int groupPosition, int count);

    // 通知組頭刪除
    public void notifyHeaderRemoved(int groupPosition);

    // 通知組尾刪除
    public void notifyFooterRemoved(int groupPosition);

    // 通知一組里的某個(gè)子項(xiàng)刪除
    public void notifyChildRemoved(int groupPosition, int childPosition);

    // 通知一組里的多個(gè)子項(xiàng)刪除
    public void notifyChildRangeRemoved(int groupPosition, int childPosition, int count);

    // 通知一組里的所有子項(xiàng)刪除
    public void notifyChildrenRemoved(int groupPosition);
    
    //****** 插入操作 *****//
    // 通知一組數(shù)據(jù)插入
    public void notifyGroupInserted(int groupPosition);

    // 通知多組數(shù)據(jù)插入
    public void notifyGroupRangeInserted(int groupPosition, int count);

    // 通知組頭插入
    public void notifyHeaderInserted(int groupPosition);
    
    // 通知組尾插入
    public void notifyFooterInserted(int groupPosition);

    // 通知一個(gè)子項(xiàng)到組里插入
    public void notifyChildInserted(int groupPosition, int childPosition);

    // 通知一組里的多個(gè)子項(xiàng)插入
    public void notifyChildRangeInserted(int groupPosition, int childPosition, int count);

    // 通知一組里的所有子項(xiàng)插入
    public void notifyChildrenInserted(int groupPosition);

3、使用GridLayoutManager的注意
如果要使用GridLayoutManager哮针,一定要使用項(xiàng)目中所提供的GroupedGridLayoutManager关面。因?yàn)榉纸M列表如果要使用GridLayoutManager實(shí)現(xiàn)網(wǎng)格布局,就要保證組的頭部和尾部是要單獨(dú)占用一行的十厢。否則組的頭等太、尾可能會(huì)跟子項(xiàng)混著一起,造成布局混亂蛮放。同時(shí)GroupedGridLayoutManager提供了對(duì)子項(xiàng)的SpanSize的修改方法缩抡,使用GroupedGridLayoutManager可以實(shí)現(xiàn)更多的復(fù)雜列表布局。

    //直接使用GroupedGridLayoutManager實(shí)現(xiàn)子項(xiàng)的Grid效果
    GroupedGridLayoutManager gridLayoutManager = new GroupedGridLayoutManager(this, 2, adapter);
   rvList.setLayoutManager(gridLayoutManager);
   

   GroupedGridLayoutManager gridLayoutManager = new GroupedGridLayoutManager(this, 4, adapter){
       //重寫(xiě)這個(gè)方法 改變子項(xiàng)的SpanSize包颁。
       //這個(gè)跟重寫(xiě)SpanSizeLookup的getSpanSize方法的使用是一樣的瞻想。
       @Override
       public int getChildSpanSize(int groupPosition, int childPosition) {
            if(groupPosition % 2 == 1){
                 return 2;
            }
            return super.getChildSpanSize(groupPosition, childPosition);
       }
   };
   rvList.setLayoutManager(gridLayoutManager);

4、BaseViewHolder的使用
項(xiàng)目中提供了一個(gè)通用的ViewHolder:BaseViewHolder娩嚼。提供了根據(jù)viewId獲取View的方法和對(duì)View蘑险、TextView、ImageView的常用設(shè)置方法岳悟。

//根據(jù)id獲取View
TextView  textView = holder.get(R.id.tv_header);

//View漠其、TextView、ImageView的常用設(shè)置方法。并且支持方法連綴調(diào)用
holder.setText(R.id.tv_header, "內(nèi)容")
                .setImageResource(R.id.iv_image, 資源id)
                .setBackgroundRes(R.id.view,資源id);

BaseViewHolder是可以通用的和屎,在普通的Adapter中也可以使用拴驮,可以省去每次都要?jiǎng)?chuàng)建ViewHolder的麻煩。

下面看一個(gè)簡(jiǎn)單的使用列子:

public class GroupedListAdapter extends GroupedRecyclerViewAdapter {

    private ArrayList<GroupEntity> mGroups;

    public GroupedListAdapter(Context context, ArrayList<GroupEntity> groups) {
        super(context);
        mGroups = groups;
    }

    @Override
    public int getGroupCount() {
        return mGroups == null ? 0 : mGroups.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        ArrayList<ChildEntity> children = mGroups.get(groupPosition).getChildren();
        return children == null ? 0 : children.size();
    }

    @Override
    public boolean hasHeader(int groupPosition) {
        return true;
    }

    @Override
    public boolean hasFooter(int groupPosition) {
        return true;
    }

    @Override
    public int getHeaderLayout(int viewType) {
        return R.layout.adapter_header;
    }

    @Override
    public int getFooterLayout(int viewType) {
        return R.layout.adapter_footer;
    }

    @Override
    public int getChildLayout(int viewType) {
        return R.layout.adapter_child;
    }

    @Override
    public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
        GroupEntity entity = mGroups.get(groupPosition);
        holder.setText(R.id.tv_header, entity.getHeader());
    }

    @Override
    public void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition) {
        GroupEntity entity = mGroups.get(groupPosition);
        holder.setText(R.id.tv_footer, entity.getFooter());
    }

    @Override
    public void onBindChildViewHolder(BaseViewHolder holder, int groupPosition, int childPosition) {
        ChildEntity entity = mGroups.get(groupPosition).getChildren().get(childPosition);
        holder.setText(R.id.tv_child, entity.getChild());
    }
}
public class GroupedListActivity extends AppCompatActivity {

    private TextView tvTitle;
    private RecyclerView rvList;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_group_list);

        tvTitle = (TextView) findViewById(R.id.tv_title);
        rvList = (RecyclerView) findViewById(R.id.rv_list);

        tvTitle.setText(R.string.group_list);

        rvList.setLayoutManager(new LinearLayoutManager(this));
        GroupedListAdapter adapter = new GroupedListAdapter(this, GroupModel.getGroups(10, 5));
        adapter.setOnHeaderClickListener(new GroupedRecyclerViewAdapter.OnHeaderClickListener() {
            @Override
            public void onHeaderClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder,
                                      int groupPosition) {
                Toast.makeText(GroupedListActivity.this, "組頭:groupPosition = " + groupPosition,
                        Toast.LENGTH_LONG).show();
            }
        });
        adapter.setOnFooterClickListener(new GroupedRecyclerViewAdapter.OnFooterClickListener() {
            @Override
            public void onFooterClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder,
                                      int groupPosition) {
                Toast.makeText(GroupedListActivity.this, "組尾:groupPosition = " + groupPosition,
                        Toast.LENGTH_LONG).show();
            }
        });
        adapter.setOnChildClickListener(new GroupedRecyclerViewAdapter.OnChildClickListener() {
            @Override
            public void onChildClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder,
                                     int groupPosition, int childPosition) {
                Toast.makeText(GroupedListActivity.this, "子項(xiàng):groupPosition = " + groupPosition
                                + ", childPosition = " + childPosition,
                        Toast.LENGTH_LONG).show();
            }
        });
        rvList.setAdapter(adapter);

    }
}

這是我在項(xiàng)目Demo中的實(shí)現(xiàn)的其中一個(gè)列子柴信。效果是上面的圖1套啤。想看源碼和更多的使用列子的歡迎訪問(wèn)我的GitHub

頭部懸浮吸頂功能
應(yīng)一些朋友的反饋随常,我在1.2.0版本中新加了列表的頭部懸浮吸頂功能潜沦。使用起來(lái)非常的簡(jiǎn)單,只需要用框架里提供的StickyHeaderLayout包裹一下你的RecyclerView就可以了绪氛。當(dāng)然唆鸡,你需要使用GroupedRecyclerViewAdapter才能看到效果。

    <!-- 用StickyHeaderLayout包裹RecyclerView -->
    <com.donkingliang.groupedadapter.widget.StickyHeaderLayout
        android:id="@+id/sticky_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </com.donkingliang.groupedadapter.widget.StickyHeaderLayout>

StickyHeaderLayout提供了一個(gè)設(shè)置是否顯示懸浮吸頂?shù)姆椒ā?/p>

    //是否吸頂枣察,默認(rèn)為true争占。
    stickyLayout.setSticky(true);

對(duì)懸浮吸頂功能的更多介紹,請(qǐng)看我的另一篇文章:《Android RecyclerView實(shí)現(xiàn)頭部懸浮吸頂效果
效果圖:

頭部吸頂?shù)牧斜?gif

使用DataBinding

GroupedRecyclerViewAdapter在1.3.0版本加入了對(duì)DataBinding的支持序目。要想在Adapter中使用DataBinding臂痕,只需要在GroupedRecyclerViewAdapter的構(gòu)造函數(shù)的useBinding參數(shù)傳true即可。

public class BindingAdapter extends GroupedRecyclerViewAdapter {

    public BindingAdapter(Context context) {
        //只要在這里傳true猿涨,Adapter就會(huì)用DataBinding的方式加載列表的item布局握童。默認(rèn)為false。
        super(context, true);
    }
}

然后同過(guò)BaseViewHolder的getBinding()就可以獲取到item對(duì)應(yīng)的ViewDataBinding對(duì)象叛赚。

    @Override
    public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
        //獲取ViewDataBinding對(duì)象澡绩。
        AdapterBindingHeaderBinding binding = holder.getBinding();
    }

    @Override
    public void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition) {
        //獲取ViewDataBinding對(duì)象。
        AdapterBindingFooterBinding binding = holder.getBinding();
    }

    @Override
    public void onBindChildViewHolder(BaseViewHolder holder, int groupPosition, int childPosition) {
        //獲取ViewDataBinding對(duì)象俺附。
        AdapterBindingChildBinding binding = holder.getBinding();
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末英古,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子昙读,更是在濱河造成了極大的恐慌召调,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛮浑,死亡現(xiàn)場(chǎng)離奇詭異唠叛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)沮稚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)艺沼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蕴掏,你說(shuō)我怎么就攤上這事障般〉骶ǎ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵挽荡,是天一觀的道長(zhǎng)藐石。 經(jīng)常有香客問(wèn)我,道長(zhǎng)定拟,這世上最難降的妖魔是什么于微? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮青自,結(jié)果婚禮上株依,老公的妹妹穿的比我還像新娘。我一直安慰自己延窜,他們只是感情好恋腕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著逆瑞,像睡著了一般荠藤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呆万,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天商源,我揣著相機(jī)與錄音车份,去河邊找鬼谋减。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扫沼,可吹牛的內(nèi)容都是我干的出爹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼缎除,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼严就!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起器罐,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤梢为,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后轰坊,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體铸董,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年肴沫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了粟害。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡颤芬,死狀恐怖悲幅,靈堂內(nèi)的尸體忽然破棺而出套鹅,到底是詐尸還是另有隱情,我是刑警寧澤汰具,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布卓鹿,位于F島的核電站,受9級(jí)特大地震影響郁副,放射性物質(zhì)發(fā)生泄漏减牺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一存谎、第九天 我趴在偏房一處隱蔽的房頂上張望拔疚。 院中可真熱鬧,春花似錦既荚、人聲如沸稚失。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)句各。三九已至,卻和暖如春晴叨,著一層夾襖步出監(jiān)牢的瞬間凿宾,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工兼蕊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留初厚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓孙技,卻偏偏與公主長(zhǎng)得像产禾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牵啦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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