记录一次完美解决双瀑布流!!!!

完美解决双瀑布流!!!!——前后的对比建议使用对比软件观看

项目 需求:

  1. 首页列表中有两个瀑布流
  2. 服务器无法将两个接口写在同一个接口中。


    image.png

项目要求:

  1. 两个瀑布流自由上拉加载无问题。
  2. 列表要流畅

解决方案一:首页中采用两个RecyclerView,采用普通写法。

用nestScrollView解决滑动冲突:

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rv_child_Push"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingStart="@dimen/space_30"
                    android:paddingEnd="@dimen/space_30"
                    android:visibility="visible" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/rv_pu_bu"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
            </LinearLayout>
        </androidx.core.widget.NestedScrollView>

结果:瀑布流一起请求完,无上拉加载效果。滑动卡顿。因为view未能得到复用。

原因:这是因为NestedScrollView 本身实现的有ScrollView相关的接口(结合Baskquickadapter)自己内部会测量和计算。Scrollview,所有的子view都会一次性被加载出来。。

解决方案二:第一个Recyclerview作为header或者footer,添加到第二个RecyclerView

结果:作为header和Footer的View,无法一次请求,也么有上拉加载效果。

原因:同样是因为header是一次加载完的原因。
我们采用第一个Recylcerview,作为header添加到第二个RecyclerView中的办法。
但是第一个的下拉刷新还是无法实现。

解决方案三:第二个RecyclerView的Item 作为第一个RecyclerView的 多条目布局中的一种条目处理。

当第一个数据的接口拉到最后一页的时候,请求第二个数据,拼接到前面就像使用第一个数据一样。

具体操作和重构流程:

  1. 两个adapter统一为一个,第二个的请求httpPager2的成功方法的数据格式发生变化。

  2. 第二个RecyclerView的LayoutManger与第一个保持一致。

  3. 在第一个瀑布流加载结束的位置,做衔接处理

  4. 下拉刷新的位置,重新添加page,并改变状态。

1) 删除一下bottomAdapter相关的方法
      bottomAdapter.setLoadMoreView(new LoadingAddDataView());
        bottomAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                JumpUtils.jumpToPlayerAct(bottomData.get(position).getVod_id());
            }
        });
        bottomAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                httpPager2();
            }
        }, rv_pu_bu);
2)两个数据衔接位置的演变:

原来1


   GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page >= body.getLast_page()) {
                    mainAdapter.loadMoreEnd(true);
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }

演变2:


  GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page >= body.getLast_page()) {
                    currentRequest = "httpPager2";
                    httpPager2();
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }

演变3:
解决第二个瀑布流的第一页一闪而过,看不到的问题。

  GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page == body.getLast_page()) {
                    mainAdapter.loadMoreComplete();
                    currentRequest = "httpPager2";
                    httpPager2();
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }
3) 添加请求变化的标志位,数据变化的时候改变这个。
 public String currentRequest = "httpPager";

下拉的时候,根据标志位决定该请求那个;

   mainAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                if ("httpPager".equals(currentRequest)) {
                    httpPager();
                } else {
                    httpPager2();
                }

            }
        }, rv_child_Push);

新版核心代码——请使用对比软件,观察两个的不同:

核心代码:只记录有差异的代码,属于代码片段

public class ChildRecommendFragment  {

    @BindView(R.id.sl_Push)
    SwipeRefreshLayout sl_Push;

    @BindView(R.id.rv_child_Push)
    RecyclerView rv_child_Push;


    @BindView(R.id.loading)
    View loading;


    @BindView(R.id.load_err)
    View load_err;


    /**
     * 上拉加载页数
     */
    public int pagePullRefresh = 1;
    public int page = 1;
    public int page2 = 1;

  

    private RecommendAdapter mainAdapter;
    private ArrayList<PushMultipleItem> multipleList = new ArrayList<>();

    public String currentRequest = "httpPager";


    @Override
    protected void initView() {
       
        LinearLayoutManager manager = new LinearLayoutManager(mActivity);
        rv_child_Push.setLayoutManager(manager);
        mainAdapter = new RecommendAdapter(null);
        rv_child_Push.setAdapter(mainAdapter);  
        //上拉加载
        mainAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                if ("httpPager".equals(currentRequest)) {
                    httpPager();
                } else {
                    httpPager2();
                }

            }
        }, rv_child_Push);

        sl_Push.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                pagePullRefresh = getRandomPageRefresh();
                page = 1;
                page2=1;
                currentRequest="httpPager";
                httpData();
            }
        });

        load_err.setOnClickListener(view -> {
            loading.setVisibility(View.VISIBLE);
            load_err.setVisibility(View.GONE);
            page = 1;
            page2=1;
            currentRequest="httpPager";
            httpData();
        });
    }

    @Override
    protected void initData() {
        loading.setVisibility(View.VISIBLE);
        httpData();
    }

     * 请求数据集合
     */
    private void httpData() {

        String url = ConstantUtils.getUrlConstant().video_type
                + "?type_id=" + getArguments().get("id")
                + "&version=" + AppUtils.getAppVersionCode()
                + "&page=" + pagePullRefresh
                + "&mobiletype=1";

        OkGoUtils.getRequest(url, new JsonCallBack<GetTypeDetailBean>(GetTypeDetailBean.class, mActivity) {
            @Override
            public void onStart(Request<GetTypeDetailBean, ? extends Request> request) {

            }

            @Override
            public void onSuccess(Response<GetTypeDetailBean> response) {
                loading.setVisibility(View.GONE);
                load_err.setVisibility(View.GONE);
                clearList();
                sl_Push.setRefreshing(false);
                GetTypeDetailBean body = response.body();               
                multipleList = bornMultipleList(body);
                mainAdapter.setNewData(multipleList);

            }

            @Override
            public void onError(Response<GetTypeDetailBean> response) {
                loading.setVisibility(View.GONE);
                sl_Push.setRefreshing(false);
                ToastUtils.showShort("连接服务器失败");
                if (mainAdapter.getData().size() == 0) {
                    load_err.setVisibility(View.VISIBLE);
                }
            }         
        });
    }



    private ArrayList<PushMultipleItem> bornMultipleList(GetTypeDetailBean body) {
        ArrayList<PushMultipleItem> multipleList = new ArrayList<>();
        GetTypeDetailBean.RenhotBean renhot = body.getRenhot();
        VideoBean recentTitleBean = new VideoBean(ConstantUtils.RECENT_ID, ConstantUtils.RECENT_VALUE);
        VideoBean hotTitleBean = new VideoBean(ConstantUtils.HITS_ID, ConstantUtils.HITS_VALUE);
        multipleList.add(new PushMultipleItem(PushMultipleItem.title, recentTitleBean));
        multipleList.add(new PushMultipleItem(PushMultipleItem.item, ConstantUtils.RECENT_KEY, renhot.getRecent()));
        multipleList.add(new PushMultipleItem(PushMultipleItem.changer, ConstantUtils.RECENT_KEY, null));
        multipleList.add(new PushMultipleItem(PushMultipleItem.title, hotTitleBean));
        multipleList.add(new PushMultipleItem(PushMultipleItem.item, ConstantUtils.HITS_KEY, renhot.getHits()));
        multipleList.add(new PushMultipleItem(PushMultipleItem.changer, ConstantUtils.HITS_KEY, null));

        return multipleList;
    }



    private void clearList() {
        if (multipleList != null && multipleList.size() > 0) {
            multipleList.clear();
        }
    }


    /**
     * 分页请求
     */
    private void httpPager() {
        OkGoUtils.getRequest(getUrl(), new JsonCallBack<GetTypeVodsBean>(GetTypeVodsBean.class, mActivity) {
            @Override
            public void onStart(Request<GetTypeVodsBean, ? extends Request> request) {
            }

            @Override
            public void onSuccess(Response<GetTypeVodsBean> response) {

                GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page == body.getLast_page()) {
                    mainAdapter.loadMoreComplete();
                    currentRequest = "httpPager2";
                    httpPager2();
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }
            }

            @Override
            public void onError(Response<GetTypeVodsBean> response) {
                mainAdapter.loadMoreFail();
            }

        
        });
    }

    @NotNull
    private String getUrl() {
        return ConstantUtils.getUrlConstant().getypevods
                + "?type_id=" + getArguments().get("id")
                + "&type_name=" + ListSharedPreferences.getTypeName((Integer) getArguments().get("id"))
                + "&page=" + page;
    }

    private void httpPager2() {
        String url = ConstantUtils.getUrlConstant().getrecentvod
                + "?type_id=" + getArguments().get("id")
                + "&type_name=" + ListSharedPreferences.getTypeName((Integer) getArguments().get("id"))
                + "&page=" + page2;

        OkGoUtils.getRequest(url, new JsonCallBack<VideoBeanBottom>(VideoBeanBottom.class, mActivity) {
            @Override
            public void onStart(Request<VideoBeanBottom, ? extends Request> request) {
            }

            @Override
            public void onSuccess(Response<VideoBeanBottom> response) {
                loading.setVisibility(View.GONE);
                VideoBeanBottom body = response.body();
                List<VideoBean> data = body.getData();
                ArrayList<PushMultipleItem> multipleItems = new ArrayList<>();
                if (page2==1){
                    VideoBean hotTitleBean = new VideoBean(ConstantUtils.FILM_LIBRARY, "我的片库");
                    multipleList.add(new PushMultipleItem(PushMultipleItem.title, hotTitleBean));
                }

                multipleItems.add(new PushMultipleItem(PushMultipleItem.item, "片库", data));
                mainAdapter.addData(multipleItems);
                if (page2 >= 10) {
                    mainAdapter.loadMoreEnd(false);
                } else {
                    page2++;
                    mainAdapter.loadMoreComplete();
                }
            }

            @Override
            public void onError(Response<VideoBeanBottom> response) {
                mainAdapter.loadMoreFail();
            }

        });
    }

    @NotNull
    private ArrayList<PushMultipleItem> getPushMultipleItems(GetTypeVodsBean body) {
        ArrayList<PushMultipleItem> multipleItems = new ArrayList<>();
        //遍历Map
        Map<String, ArrayList<VideoBean>> vods = body.getVods();
        Map<String, ArrayList<SubjectsBean>> beans = body.getSubjects();
        if (vods != null && beans != null) {
            for (String key : vods.keySet()) {
                ArrayList<VideoBean> videoBeans = vods.get(key);
                ArrayList<SubjectsBean> zhuanTiBannerBeans = beans.get(key);
                if (videoBeans != null && videoBeans.size() > 0) {
                    VideoBean bean = new VideoBean();
                    bean.setVod_name(ListSharedPreferences.getTypeName(Integer.parseInt(key)));
                    bean.setVod_id(Integer.parseInt(key));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.title, bean));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.banner, zhuanTiBannerBeans));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.item, key, videoBeans));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.changer, key, null));
                }
            }
        }
        return multipleItems;
    }
    }

老版核心代码——请使用对比软件,观察两个的不同:

public class ChildRecommendFragment  {

    @BindView(R.id.sl_Push)
    SwipeRefreshLayout sl_Push;

    @BindView(R.id.rv_pu_bu)
    RecyclerView rv_pu_bu;


    @BindView(R.id.loading)
    View loading;


    @BindView(R.id.load_err)
    View load_err;


    /**
     * 上拉加载页数
     */
    public int pagePullRefresh = 1;
    public int page = 1;
    public int page2 = 1;
    private RecommendAdapter mainAdapter;
    private RecommendAdapter bottomAdapter;
    private ArrayList<PushMultipleItem> multipleList = new ArrayList<>();
    private ArrayList<VideoBean> bottomData = new ArrayList<>();
  

    @Override
    protected void initView() {
        View bannerAdLayout = View.inflate(getContext(), R.layout.item_push_head_child, null);
        initBanner(bannerAdLayout);
        adImage = bannerAdLayout.findViewById(R.id.adImage);
        View head_big_recommend = View.inflate(getContext(), R.layout.head_big_recommend, null);
        RecyclerView rv_child_Push = head_big_recommend.findViewById(R.id.rv_child_Push);
        LinearLayoutManager manager = new LinearLayoutManager(mActivity);
        rv_child_Push.setLayoutManager(manager);

        mainAdapter = new RecommendAdapter(null);
        rv_child_Push.setAdapter(mainAdapter);

        LinearLayoutManager manager2 = new LinearLayoutManager(mActivity);
        rv_pu_bu.setLayoutManager(manager2);
        bottomAdapter = new RecommendAdapter(null);
        bottomAdapter.addHeaderView(head_big_recommend);
        rv_pu_bu.setAdapter(bottomAdapter);

        mainAdapter.addHeaderView(bannerAdLayout);
        pianKuHeader = View.inflate(getContext(), R.layout.header_title, null);
        mainAdapter.addFooterView(pianKuHeader, ConstantUtils.getSpanCount());


      
        //上拉加载
        mainAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                httpPager();
            }
        }, rv_child_Push);
        bottomAdapter.setLoadMoreView(new LoadingAddDataView());
        bottomAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                JumpUtils.jumpToPlayerAct(bottomData.get(position).getVod_id());
            }
        });
        bottomAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                httpPager2();
            }
        }, rv_pu_bu);

        sl_Push.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                pagePullRefresh = getRandomPageRefresh();
                page = 1;
                httpData();
            }
        });

        load_err.setOnClickListener(view -> {
            loading.setVisibility(View.VISIBLE);
            load_err.setVisibility(View.GONE);
            page = 1;
            httpData();
        });


    }

  
   

    @Override
    protected void initData() {
        loading.setVisibility(View.VISIBLE);
        httpData();
        page2 = 1;
        httpPager2();
    }

  

    /**
     * 请求数据集合
     */
    private void httpData() {

        String url = ConstantUtils.getUrlConstant().video_type
                + "?type_id=" + getArguments().get("id")
                + "&version=" + AppUtils.getAppVersionCode()
                + "&page=" + pagePullRefresh
                + "&mobiletype=1";

        OkGoUtils.getRequest(url, new JsonCallBack<GetTypeDetailBean>(GetTypeDetailBean.class, mActivity) {
            @Override
            public void onStart(Request<GetTypeDetailBean, ? extends Request> request) {

            }

            @Override
            public void onSuccess(Response<GetTypeDetailBean> response) {
                loading.setVisibility(View.GONE);
                load_err.setVisibility(View.GONE);
                clearList();
                sl_Push.setRefreshing(false);
                GetTypeDetailBean body = response.body();
                multipleList = bornMultipleList(body);
                mainAdapter.setNewData(multipleList);

            }

            @Override
            public void onError(Response<GetTypeDetailBean> response) {
                loading.setVisibility(View.GONE);
                sl_Push.setRefreshing(false);
                ToastUtils.showShort("连接服务器失败");
                if (mainAdapter.getData().size() == 0) {
                    load_err.setVisibility(View.VISIBLE);
                }


            }

         
        });
    }


  

    private String getHotVideoNewUrl(String id) {
        return ConstantUtils.getUrlConstant().gethotvodnew
                + "?type_id=" + id
                + "&page=" + MyAppUtils.getRandomPage();
    }


    private ArrayList<PushMultipleItem> bornMultipleList(GetTypeDetailBean body) {
        ArrayList<PushMultipleItem> multipleList = new ArrayList<>();
        GetTypeDetailBean.RenhotBean renhot = body.getRenhot();
        VideoBean recentTitleBean = new VideoBean(ConstantUtils.RECENT_ID, ConstantUtils.RECENT_VALUE);
        VideoBean hotTitleBean = new VideoBean(ConstantUtils.HITS_ID, ConstantUtils.HITS_VALUE);
        multipleList.add(new PushMultipleItem(PushMultipleItem.title, recentTitleBean));
        multipleList.add(new PushMultipleItem(PushMultipleItem.item, ConstantUtils.RECENT_KEY, renhot.getRecent()));
        multipleList.add(new PushMultipleItem(PushMultipleItem.changer, ConstantUtils.RECENT_KEY, null));
        multipleList.add(new PushMultipleItem(PushMultipleItem.title, hotTitleBean));
        multipleList.add(new PushMultipleItem(PushMultipleItem.item, ConstantUtils.HITS_KEY, renhot.getHits()));
        multipleList.add(new PushMultipleItem(PushMultipleItem.changer, ConstantUtils.HITS_KEY, null));

        return multipleList;
    }

 

    private void clearList() {
        if (multipleList != null && multipleList.size() > 0) {
            multipleList.clear();
        }
    }


    /**
     * 分页请求
     */
    private void httpPager() {
        OkGoUtils.getRequest(getUrl(), new JsonCallBack<GetTypeVodsBean>(GetTypeVodsBean.class, mActivity) {
            @Override
            public void onStart(Request<GetTypeVodsBean, ? extends Request> request) {
            }

            @Override
            public void onSuccess(Response<GetTypeVodsBean> response) {

                GetTypeVodsBean body = response.body();
                mainAdapter.addData(getPushMultipleItems(body));
                if (page >= body.getLast_page()) {
                    mainAdapter.loadMoreEnd(true);
                } else {
                    page++;
                    mainAdapter.loadMoreComplete();
                }
            }

            @Override
            public void onError(Response<GetTypeVodsBean> response) {
                mainAdapter.loadMoreFail();
            }          
        });
    }

    @NotNull
    private String getUrl() {
        return ConstantUtils.getUrlConstant().getypevods
                + "?type_id=" + getArguments().get("id")
                + "&type_name=" + ListSharedPreferences.getTypeName((Integer) getArguments().get("id"))
                + "&page=" + page;
    }

    private void httpPager2() {
        String url = ConstantUtils.getUrlConstant().getrecentvod
                + "?type_id=" + getArguments().get("id")
                + "&type_name=" + ListSharedPreferences.getTypeName((Integer) getArguments().get("id"))
                + "&page=" + page2;

        OkGoUtils.getRequest(url, new JsonCallBack<VideoBeanBottom>(VideoBeanBottom.class, mActivity) {
            @Override
            public void onStart(Request<VideoBeanBottom, ? extends Request> request) {
            }

            @Override
            public void onSuccess(Response<VideoBeanBottom> response) {
                if (pianKuHeader != null) {
                    pianKuHeader.setVisibility(View.VISIBLE);
                }
                loading.setVisibility(View.GONE);
                VideoBeanBottom body = response.body();
                List<VideoBean> data = body.getData();
                ArrayList<PushMultipleItem> multipleItems = new ArrayList<>();
                multipleItems.add(new PushMultipleItem(PushMultipleItem.item, "片库", data));
                bottomAdapter.addData(multipleItems);
                if (page2 >= 10) {
                    bottomAdapter.loadMoreEnd(false);
                } else {
                    page2++;
                    bottomAdapter.loadMoreComplete();
                }
            }

            @Override
            public void onError(Response<VideoBeanBottom> response) {
                bottomAdapter.loadMoreFail();
            }
        });
    }

    @NotNull
    private ArrayList<PushMultipleItem> getPushMultipleItems(GetTypeVodsBean body) {
        ArrayList<PushMultipleItem> multipleItems = new ArrayList<>();
        //遍历Map
        Map<String, ArrayList<VideoBean>> vods = body.getVods();
        Map<String, ArrayList<SubjectsBean>> beans = body.getSubjects();
        if (vods != null && beans != null) {
            for (String key : vods.keySet()) {
                ArrayList<VideoBean> videoBeans = vods.get(key);
                ArrayList<SubjectsBean> zhuanTiBannerBeans = beans.get(key);
                if (videoBeans != null && videoBeans.size() > 0) {
                    VideoBean bean = new VideoBean();
                    bean.setVod_name(ListSharedPreferences.getTypeName(Integer.parseInt(key)));
                    bean.setVod_id(Integer.parseInt(key));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.title, bean));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.banner, zhuanTiBannerBeans));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.item, key, videoBeans));
                    multipleItems.add(new PushMultipleItem(PushMultipleItem.changer, key, null));
                }
            }
        }
        return multipleItems;
    }


}

对比效果如图:

下拉刷新部分.png

第一个加载到底的是数据衔接部分
统一Adapter后,将第二个adapter换成第一个adapter

大概这也是我能想到的最好的办法了——核心代码用对比软件对比

参考链接:https://www.jianshu.com/p/1add7d5a4ec4
https://www.jianshu.com/p/34d2c5cdb3fb

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352