RecyclerView完全解析(四)——與SwipeRefreshLayout實(shí)現(xiàn)下拉刷新與上拉加載

特別聲明:

一瞳氓、前言

  • 話說RecyclerView已經(jīng)面市很久,也在很多應(yīng)用中得到廣泛的使用君旦,在整個(gè)開發(fā)者圈子里面也擁有很不錯(cuò)的口碑桩撮,那說明RecyclerView擁有比ListView,GridView之類控件有很多的優(yōu)點(diǎn)犬第,例如:數(shù)據(jù)綁定厦画,Item View創(chuàng)建,View的回收以及重用等機(jī)制。前三三篇文章已經(jīng)貢呢更新了以下三個(gè)部分:

1吝梅、RecyclerView控件的基本使用,包括基礎(chǔ),進(jìn)階,高級(jí)部分,動(dòng)畫之類(點(diǎn)擊進(jìn)入)
2、RecyclerView控件的實(shí)戰(zhàn)實(shí)例(點(diǎn)擊進(jìn)入)
3惹骂、RecyclerView控件集合AA(Android Annotations)注入框架實(shí)例(點(diǎn)擊進(jìn)入)

  • 本來這個(gè)專題不打算更新苏携,不過前兩天看到各位童鞋還是挺積極的評(píng)論到,希望可以更新RecyclerView加入下拉刷新和上拉加載更多的功能对粪。正好昨天周末右冻,所以我這邊也就實(shí)現(xiàn)了這樣的功能,今天更新一下著拭。具體代碼已經(jīng)上傳到下面的項(xiàng)目中纱扭,歡迎各位去star和fork一下:

FastDev4Android框架項(xiàng)目地址:https://github.com/jiangqqlmj/FastDev4Android

  • RecyclerView實(shí)現(xiàn)的列表,默認(rèn)情況下面是不帶下拉刷新和上拉記載更多效果的茫死,但是我在我們的實(shí)際項(xiàng)目當(dāng)中跪但,為了提高用戶體驗(yàn)履羞,這種效果一般都需要實(shí)現(xiàn)峦萎,在我以前的博客中已經(jīng)重寫了ListView(Android 列表下拉刷新組件PullToRefreshListView使用)實(shí)現(xiàn)上拉刷新和上拉加載更多效果÷啪茫現(xiàn)在我們已經(jīng)學(xué)會(huì)了ListView,GridView的替代品RecyclerView的基本使用方法,那么必不可少的也需要實(shí)現(xiàn)上拉刷新和上拉加載更多的效果了爱榔。今天我們會(huì)通過兩種方式來實(shí)現(xiàn)被环,具體會(huì)采用Android的另一控件SwipeRefreshLayout。

二详幽、SwipeRefreshLayout介紹

  • SwipeRefrshLayout是Google官方更新的一個(gè)Widget,可以實(shí)現(xiàn)下拉刷新的效果筛欢。該控件集成自ViewGroup在support-v4兼容包下,不過我們需要升級(jí)supportlibrary的版本到19.1以上唇聘“婀茫基本使用的方法如下:
  • setOnRefreshListener(OnRefreshListener):添加下拉刷新監(jiān)聽器
  • setRefreshing(boolean):顯示或者隱藏刷新進(jìn)度條

  • isRefreshing():檢查是否處于刷新狀態(tài)

  • setColorSchemeResources():設(shè)置進(jìn)度條的顏色主題,最多設(shè)置四種迟郎,以前的setColorScheme()方法已經(jīng)棄用了剥险。

  • 具體使用效果下面我們會(huì)看到。

三宪肖、RecyclerView+SwpieRefreshLayout實(shí)現(xiàn)下拉刷新效果

1表制、SwipeRefreshLayout本身自帶下拉刷新的效果,那么我們可以選擇在RecyclerView布局外部嵌套一層SwipeRefreshLayout布局即可

  • 具體布局文件如下:
<?xmlversionxmlversion="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"android:layout_width="match_parent"  
    android:layout_height="match_parent">  
    
    <android.support.v4.widget.SwipeRefreshLayout  
       android:id="@+id/demo_swiperefreshlayout"  
       android:layout_width="fill_parent"  
       android:layout_height="fill_parent"  
       android:scrollbars="vertical"  
        >  
       <android.support.v7.widget.RecyclerView  
           android:id="@+id/demo_recycler"  
           android:layout_width="fill_parent"  
           android:layout_height="fill_parent"  
           ></android.support.v7.widget.RecyclerView>  
   </android.support.v4.widget.SwipeRefreshLayout>  
</LinearLayout>  

2控乾、接著在Activity中獲取SwipeRefreshLayout控件并且設(shè)置OnRefreshListener監(jiān)聽器么介,同時(shí)實(shí)現(xiàn)里邊的onRefresh()方法,在該方法中進(jìn)行網(wǎng)絡(luò)請(qǐng)求最新數(shù)據(jù)蜕衡,然后刷新RecyclerView列表同時(shí)設(shè)置SwipeRefreshLayout的進(jìn)度Bar的隱藏或者顯示效果壤短。

  • 具體代碼如下:
demo_swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {  
            @Override  
            public void onRefresh() {  
                Log.d("zttjiangqq","invoke onRefresh...");  
                new Handler().postDelayed(newRunnable() {  
                    @Override  
                    public void run() {  
                        List<String> newDatas = new ArrayList<String>();  
                        for (int i = 0; i <5; i++) {  
                            int index = i + 1;  
                           newDatas.add("new item" + index);  
                        }  
                       adapter.addItem(newDatas);  
                       demo_swiperefreshlayout.setRefreshing(false);  
                       Toast.makeText(RecyclerRefreshActivity.this, "更新了五條數(shù)據(jù)...", Toast.LENGTH_SHORT).show();  
                    }  
                }, 5000);  
            }  
   });  

3、除此之外我們也來看一下Adapter和Activity中的其他代碼衷咽,也方便各位童鞋查看鸽扁。

RecyclerRefreshActivity.java

public class RecyclerRefreshActivity extends BaseActivity {  
    private SwipeRefreshLayout demo_swiperefreshlayout;  
    private RecyclerView demo_recycler;  
    private RefreshRecyclerAdapter adapter;  
    private LinearLayoutManager linearLayoutManager;  
    private int lastVisibleItem;  
    @Override  
    protected void onCreate(BundlesavedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.recycler_refresh_layout);  
        
        demo_swiperefreshlayout=(SwipeRefreshLayout)this.findViewById(R.id.demo_swiperefreshlayout);  
        demo_recycler=(RecyclerView)this.findViewById(R.id.demo_recycler);  
        //設(shè)置刷新時(shí)動(dòng)畫的顏色,可以設(shè)置4個(gè)  
        demo_swiperefreshlayout.setProgressBackgroundColorSchemeResource(android.R.color.white);  
        demo_swiperefreshlayout.setColorSchemeResources(android.R.color.holo_blue_light,  
                android.R.color.holo_red_light,android.R.color.holo_orange_light,  
               android.R.color.holo_green_light);  
        demo_swiperefreshlayout.setProgressViewOffset(false, 0, (int) TypedValue  
               .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources()  
                        .getDisplayMetrics()));  

        linearLayoutManager=new LinearLayoutManager(this);  
        linearLayoutManager.setOrientation(OrientationHelper.VERTICAL);  
        demo_recycler.setLayoutManager(linearLayoutManager);  
        //添加分隔線  
        demo_recycler.addItemDecoration(new AdvanceDecoration(this, OrientationHelper.VERTICAL));  
        demo_recycler.setAdapter(adapter = new RefreshRecyclerAdapter(this));  
        //設(shè)置下拉刷新監(jiān)聽
        demo_swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {  
            @Override  
            public void onRefresh() {  
                Log.d("zttjiangqq","invoke onRefresh...");  
                new Handler().postDelayed(newRunnable() {  
                    @Override  
                    public void run() {  
                        List<String> newDatas = new ArrayList<String>();  
                        for (int i = 0; i <5; i++) {  
                            int index = i + 1;  
                           newDatas.add("new item" + index);  
                        }  
                       adapter.addItem(newDatas);  
                       demo_swiperefreshlayout.setRefreshing(false);  
                       Toast.makeText(RecyclerRefreshActivity.this, "更新了五條數(shù)據(jù)...", Toast.LENGTH_SHORT).show();  
                    }  
                }, 5000);  
            }  
        });  
          
}  

***RefreshRecyclerAdapter.java ***

public class RefreshRecyclerAdapter extends RecyclerView.Adapter<RefreshRecyclerAdapter.ViewHolder>{  
    private LayoutInflater mInflater;  
    private List<String> mTitles=null;  
    public RefreshRecyclerAdapter(Context context){  
       this.mInflater=LayoutInflater.from(context);  
        this.mTitles=new ArrayList<String>();  
        for (int i=0;i<20;i++){  
            int index=i+1;  
           mTitles.add("item"+index);  
        }  
    }  
    /** 
     * item顯示類型 
     * @param parent 
     * @param viewType 
     * @return 
     */  
    @Override  
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
        final Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false);  
        //這邊可以做一些屬性設(shè)置镶骗,甚至事件監(jiān)聽綁定  
        //view.setBackgroundColor(Color.RED);  
        ViewHolder viewHolder=new ViewHolder(view);  
   
        return viewHolder;  
    }  
   
    /** 
     * 數(shù)據(jù)的綁定顯示 
     * @param holder 
     * @param position 
     */  
    @Override  
    public void onBindViewHolder(ViewHolder holder, int position) {  
       holder.item_tv.setText(mTitles.get(position));  
        holder.itemView.setTag(position);  
    }  
    @Override  
    public int getItemCount() {  
        return mTitles.size();  
    }  
   
    //自定義的ViewHolder桶现,持有每個(gè)Item的的所有界面元素  
    public static class ViewHolder extends RecyclerView.ViewHolder {  
        public TextView item_tv;  
        public ViewHolder(View view){  
            super(view);  
            item_tv = (TextView)view.findViewById(R.id.item_tv);  
        }  
    }  
   
    //添加數(shù)據(jù)  
    public void addItem(List<String> newDatas) {  
        //mTitles.add(position, data);  
        //notifyItemInserted(position);  
        newDatas.addAll(mTitles);  
        mTitles.removeAll(mTitles);  
        mTitles.addAll(newDatas);  
        notifyDataSetChanged();  
    }  
   
    public void addMoreItem(List<String> newDatas) {  
        mTitles.addAll(newDatas);  
        notifyDataSetChanged();  
    }  
}  
  • 以上重要地方的注釋已經(jīng)加上去了。

4鼎姊、運(yùn)行效果大致如下:

.gif

如無法顯示圖片:點(diǎn)擊此鏈接查看

四骡和、RecyclerView設(shè)置滾動(dòng)事件加入上拉加載更多功能

  • 下面我們?cè)賮砜碦ecyclerView和相關(guān)類的一些特性:

LayoutManger給我們提供了以下幾個(gè)方法來讓開發(fā)者方便的獲取到屏幕上面的頂部item和頂部item相關(guān)的信息:

  • findFirstVisibleItemPosition()
  • findFirstCompletlyVisibleItemPosition()
  • findLastVisibleItemPosition()
  • findLastCompletlyVisibleItemPosition()

同時(shí)通過Recycler.Adapter的getItemCount()方法可以輕松獲取到RecyclerView列表中Item View的個(gè)數(shù)。

  • 那么下面我們通過監(jiān)聽滑動(dòng)(滾動(dòng))事件相寇,然后在里邊判斷是否已經(jīng)滑動(dòng)到最底部來加載更多的數(shù)據(jù)慰于,使用方法如下:
       //RecyclerView滑動(dòng)監(jiān)聽  
       demo_recycler.setOnScrollListener(new RecyclerView.OnScrollListener() {  
           @Override  
           public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  
              super.onScrollStateChanged(recyclerView, newState);  
               if (newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 ==adapter.getItemCount()) {  
                   new Handler().postDelayed(new Runnable() {  
                       @Override  
                       public void run() {  
                           List<String> newDatas = new ArrayList<String>();  
                           for (int i = 0; i< 5; i++) {  
                               int index = i +1;  
                              newDatas.add("more item" + index);  
                           }  
                          adapter.addMoreItem(newDatas);  
                       }  
                   },1000);  
               }  
           }  
           @Override  
           public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
               super.onScrolled(recyclerView,dx, dy);  
               lastVisibleItem =linearLayoutManager.findLastVisibleItemPosition();  
           }  
       });  
  • 運(yùn)行效果如下:


    .gif

如不能顯示效果圖:點(diǎn)擊此鏈接查看

五、升級(jí)RecyclerView加入FootView實(shí)現(xiàn)上拉加載

  • 上面我們雖然已經(jīng)實(shí)現(xiàn)了上拉加載更多的效果唤衫,但是還比較丑陋婆赠,最起碼要讓用戶知道確實(shí)在上拉加載的過程吧,例如加載一個(gè)底部的進(jìn)度布局佳励。這樣一想休里,那么我們就按照ListView方式addFootView()唄蛆挫,不過很可惜的是RecyclerView沒有給我們提供addFootView()方法,那該怎么樣辦呢妙黍?

我們來看RecyclerView.Apapter類:

  • 我們要實(shí)現(xiàn)一個(gè)自定義Adapter一定需要實(shí)現(xiàn)onCreateViewHolder(ViewGroup paren,int viewType)方法悴侵,注意看方法中的第二個(gè)參數(shù)viewType,是不是想到布局類型了拭嫁,也就是說該也支持多套布局顯示的可免,那么查看基類中的所有方法如下:


上面有一個(gè)方法getItemType(),這個(gè)就和ListView的Adapter的實(shí)現(xiàn)差不多了,那么我們這邊可以使用多套布局給RecyclerView加入一個(gè)FootView布局即可做粤。

RefreshFootAdapter.Java具體實(shí)現(xiàn)流程如下:

1浇借、加入布局狀態(tài)標(biāo)志-用來判斷此時(shí)加載是普通Item還是foot view:

 private static final int TYPE_ITEM =0;  //普通Item View
 private static final intTYPE_FOOTER = 1;  //頂部FootView

2、重寫getItemCount()方法,返回的Item數(shù)量在數(shù)據(jù)的基礎(chǔ)上面+1怕品,增加一項(xiàng)FootView布局項(xiàng):

//返回的總條目數(shù) +1
public intgetItemCount() {  
     return mTitles.size()+1;  
 }  

3逮刨、重寫getItemViewType方法來判斷返回加載的布局的類型:

public int getItemViewType(int position) {  
    // 最后一個(gè)item設(shè)置為footerView  
    if (position + 1 == getItemCount()) {  
        return TYPE_FOOTER;  
    } else {  
        return TYPE_ITEM;  
    }  
 }  

4、接著onCreateViewHolder(ViewGroup parent,int viewType)加載布局的時(shí)候根據(jù)viewType的類型來選擇指定的布局創(chuàng)建堵泽,返回即可:

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
        //進(jìn)行判斷顯示類型修己,來創(chuàng)建返回不同的View  
        if(viewType==TYPE_ITEM){  
            Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false);  
            //這邊可以做一些屬性設(shè)置,甚至事件監(jiān)聽綁定  
            //view.setBackgroundColor(Color.RED);  
            ItemViewHolder itemViewHolder=new ItemViewHolder(view);  
            return itemViewHolder;  
        }else if(viewType==TYPE_FOOTER){  
            Viewfoot_view=mInflater.inflate(R.layout.recycler_load_more_layout,parent,false);  
            //這邊可以做一些屬性設(shè)置迎罗,甚至事件監(jiān)聽綁定  
            //view.setBackgroundColor(Color.RED);  
            FootViewHolder footViewHolder=new FootViewHolder(foot_view);  
            return footViewHolder;  
        }  
       return null;  
}  

5睬愤、最后進(jìn)行判斷數(shù)據(jù)的時(shí)候(onBindViewHolder),判斷holder的類型來進(jìn)行判定數(shù)據(jù)即可:

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
       if(holder instanceof ItemViewHolder) {  
          ((ItemViewHolder)holder).item_tv.setText(mTitles.get(position));  
           holder.itemView.setTag(position);  
       }else if(holder instanceof FootViewHolder){  
           FootViewHolderfootViewHolder=(FootViewHolder)holder;  
           switch (load_more_status){  
               case PULLUP_LOAD_MORE:  
                  footViewHolder.foot_view_item_tv.setText("上拉加載更多...");  
                   break;  
               case LOADING_MORE:  
                  footViewHolder.foot_view_item_tv.setText("正在加載更多數(shù)據(jù)...");  
                   break;  
           }  
       }  
} 

6纹安、整個(gè)RefreshFootAdapter完整代碼如下:

  • 同時(shí)該Adaper中我們還可以定義一個(gè)changeMoreStatus()方法和兩個(gè)字符串常量可以來進(jìn)行修改FootView中字符串提醒文本的尤辱。
public class RefreshFootAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{  
    //上拉加載更多  
    public static final int  PULLUP_LOAD_MORE=0;  
    //正在加載中  
    public static final int  LOADING_MORE=1;  
    //上拉加載更多狀態(tài)-默認(rèn)為0  
    private int load_more_status=0;  
    private LayoutInflater mInflater;  
    private List<String> mTitles=null;  
    private static final intTYPE_ITEM = 0;  //普通Item View  
    private static final intTYPE_FOOTER = 1;  //頂部FootView  
    public RefreshFootAdapter(Context context){  
       this.mInflater=LayoutInflater.from(context);  
        this.mTitles=new ArrayList<String>();  
        for (int i=0;i<20;i++){  
            int index=i+1;  
           mTitles.add("item"+index);  
        }  
    }  
    /** 
     * item顯示類型 
     * @param parent 
     * @param viewType 
     * @return 
     */  
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
        //進(jìn)行判斷顯示類型,來創(chuàng)建返回不同的View  
        if(viewType==TYPE_ITEM){  
            Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false);  
            //這邊可以做一些屬性設(shè)置厢岂,甚至事件監(jiān)聽綁定  
           //view.setBackgroundColor(Color.RED);  
            ItemViewHolder itemViewHolder=new ItemViewHolder(view);  
            return itemViewHolder;  
        }else if(viewType==TYPE_FOOTER){  
            Viewfoot_view=mInflater.inflate(R.layout.recycler_load_more_layout,parent,false);  
            //這邊可以做一些屬性設(shè)置光督,甚至事件監(jiān)聽綁定  
           //view.setBackgroundColor(Color.RED);  
            FootViewHolder footViewHolder=new FootViewHolder(foot_view);  
            return footViewHolder;  
        }  
       return null;  
    }  
   
    /** 
     * 數(shù)據(jù)的綁定顯示 
     * @param holder 
     * @param position 
     */  
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {  
        if(holder instanceof ItemViewHolder) {  
           ((ItemViewHolder)holder).item_tv.setText(mTitles.get(position));  
            holder.itemView.setTag(position);  
        }else if(holder instanceof FootViewHolder){  
            FootViewHolder footViewHolder=(FootViewHolder)holder;  
            switch (load_more_status){  
                case PULLUP_LOAD_MORE:  
                   footViewHolder.foot_view_item_tv.setText("上拉加載更多...");  
                    break;  
                case LOADING_MORE:  
                   footViewHolder.foot_view_item_tv.setText("正在加載更多數(shù)據(jù)...");  
                    break;  
            }  
        }  
    }  
   
    /** 
     * 進(jìn)行判斷是普通Item視圖還是FootView視圖 
     * @param position 
     * @return 
     */  
    @Override  
    public int getItemViewType(int position) {  
    // 最后一個(gè)item設(shè)置為footerView  
    if (position + 1 == getItemCount()) {  
                return TYPE_FOOTER;  
            } else {  
                return TYPE_ITEM;  
            }  
        }  
    @Override  
    public int getItemCount() {  
        return mTitles.size()+1;  
    }  
    //自定義的ViewHolder,持有每個(gè)Item的的所有界面元素  
    public static class ItemViewHolder extends RecyclerView.ViewHolder {  
        public TextView item_tv;  
        public ItemViewHolder(View view){  
            super(view);  
            item_tv = (TextView)view.findViewById(R.id.item_tv);  
        }  
    }  
    /** 
     * 底部FootView布局 
     */  
    public static class FootViewHolder extends  RecyclerView.ViewHolder{  
        private TextView foot_view_item_tv;  
        public FootViewHolder(View view) {  
            super(view);  
           foot_view_item_tv=(TextView)view.findViewById(R.id.foot_view_item_tv);  
        }  
    }  
   
    //添加數(shù)據(jù)  
    public void addItem(List<String> newDatas) {  
        //mTitles.add(position, data);  
        //notifyItemInserted(position);  
        newDatas.addAll(mTitles);  
        mTitles.removeAll(mTitles);  
        mTitles.addAll(newDatas);  
        notifyDataSetChanged();  
    }  
   
    public void addMoreItem(List<String> newDatas) {  
        mTitles.addAll(newDatas);  
        notifyDataSetChanged();  
    }  
   
    /** 
     * //上拉加載更多 
     * PULLUP_LOAD_MORE=0; 
     * //正在加載中 
     * LOADING_MORE=1; 
     * //加載完成已經(jīng)沒有更多數(shù)據(jù)了 
     * NO_MORE_DATA=2; 
     * @param status 
     */  
    public void changeMoreStatus(int status){  
        load_more_status=status;  
        notifyDataSetChanged();  
    }  
}  

7塔粒、整體Activity中還是設(shè)置監(jiān)聽RecyclerView的滾動(dòng)事件.代碼和第一個(gè)例子差不多,不過RecyclerView需要設(shè)置這邊的Adapter了,demo_recycler.setAdapter(adapter= new RefreshFootAdapter(this)):

//設(shè)置滑動(dòng)監(jiān)聽
demo_recycler.setOnScrollListener(new RecyclerView.OnScrollListener() {  
            @Override  
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {  
               super.onScrollStateChanged(recyclerView, newState);  
                if (newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 ==adapter.getItemCount()) {  
                    adapter.changeMoreStatus(RefreshFootAdapter.LOADING_MORE);  
                    newHandler().postDelayed(new Runnable() {  
                        @Override  
                        public void run() {  
                            List<String> newDatas = new ArrayList<String>();  
                            for (int i = 0; i< 5; i++) {  
                                int index = i +1;  
                               newDatas.add("more item" + index);  
                            }  
                           adapter.addMoreItem(newDatas);  
                           adapter.changeMoreStatus(RefreshFootAdapter.PULLUP_LOAD_MORE);  
                        }  
                    }, 2500);  
                }  
            }  
            @Override  
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {  
                super.onScrolled(recyclerView,dx, dy);  
                lastVisibleItem =linearLayoutManager.findLastVisibleItemPosition();  
            }  
 });  

8结借、運(yùn)行效果大致如下:

六、最后總結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末圃酵,一起剝皮案震驚了整個(gè)濱河市柳畔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郭赐,老刑警劉巖薪韩,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡俘陷,警方通過查閱死者的電腦和手機(jī)张惹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岭洲,“玉大人,你說我怎么就攤上這事坎匿《苁#” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵替蔬,是天一觀的道長(zhǎng)告私。 經(jīng)常有香客問我,道長(zhǎng)承桥,這世上最難降的妖魔是什么驻粟? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮凶异,結(jié)果婚禮上蜀撑,老公的妹妹穿的比我還像新娘。我一直安慰自己剩彬,他們只是感情好酷麦,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著喉恋,像睡著了一般沃饶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上轻黑,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天糊肤,我揣著相機(jī)與錄音,去河邊找鬼氓鄙。 笑死馆揉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抖拦。 我是一名探鬼主播把介,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蟋座!你這毒婦竟也來了拗踢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤向臀,失蹤者是張志新(化名)和其女友劉穎巢墅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡君纫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年驯遇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓄髓。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叉庐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出会喝,到底是詐尸還是另有隱情陡叠,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布肢执,位于F島的核電站枉阵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏预茄。R本人自食惡果不足惜兴溜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耻陕。 院中可真熱鬧拙徽,春花似錦、人聲如沸诗宣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)梧田。三九已至淳蔼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間裁眯,已是汗流浹背鹉梨。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留穿稳,地道東北人存皂。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像逢艘,于是被迫代替她去往敵國(guó)和親旦袋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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