Android雙向列表左右聯(lián)動效果

轉(zhuǎn)載請作明出處:http://www.reibang.com/p/82ced8707f2b

開篇

前一段時間有一個需求们衙,需要做一個左右雙向聯(lián)動的列表钾怔。類似于餓了么點餐頁面,但是遠沒有那么復(fù)雜蒙挑,只是用于展示的一個頁面宗侦。不是很復(fù)雜,做完已經(jīng)很久了忆蚀,目前為止沒有出現(xiàn)什么問題矾利,所以在此將它分享給大家姑裂。

番外

此功能依賴于BaseRecyclerViewAdapterHelper的adapter框架編寫,如果各位看官沒有接觸過這個庫男旗,請先點擊鏈接舶斧,大致了解過后再回來看此文章,事半功倍(強烈推薦此庫察皇,太好用了)茴厉。


先看一下效果圖吧,下圖是做好的demo的效果圖:
效果圖

首先是布局什荣,布局文件是兩個RecyclerView矾缓,和一個TextView組成。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rec_left"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@color/white" />

    <View
        android:layout_width="0.5dp"
        android:layout_height="match_parent"
        android:background="@color/divider" />

    <FrameLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rec_right"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <TextView
            android:id="@+id/right_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/divider"
            android:paddingBottom="@dimen/dp10"
            android:paddingLeft="@dimen/dp13"
            android:paddingRight="@dimen/dp10"
            android:paddingTop="@dimen/dp10"
            android:singleLine="true"
            android:textColor="@color/black"
            android:textSize="@dimen/sp16" />
    </FrameLayout>
</LinearLayout>

功能

然后再看一下數(shù)據(jù)格式吧(由于是自己寫的demo稻爬,所以數(shù)據(jù)格式只是簡單的處理了一下嗜闻,在正常開發(fā)的時候,這個格式需要同后臺同事協(xié)商好):

//獲取數(shù)據(jù)(若請求服務(wù)端數(shù)據(jù),請求到的列表需有序排列)
private void initData() {
    left = new ArrayList<>();
    left.add("第一組");
    left.add("第二組略略略略略略略");
    left.add("第三組哈哈哈哈哈哈哈哈哈哈hahahahahahaha");
    left.add("第四組哈哈哈哈哈嗝~");
    left.add("第五組");
    left.add("第六組哎呀我去");
    left.add("第七組");

    right = new ArrayList<>();

    right.add(new ScrollBean(true, left.get(0)));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("1111111", left.get(0))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("1111111", left.get(0))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("1111111", left.get(0))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("1111111", left.get(0))));

    right.add(new ScrollBean(true, left.get(1)));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("2222222", left.get(1))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("2222222", left.get(1))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("2222222", left.get(1))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("2222222", left.get(1))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("2222222", left.get(1))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("2222222", left.get(1))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("2222222", left.get(1))));

    right.add(new ScrollBean(true, left.get(2)));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("3333333", left.get(2))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("3333333", left.get(2))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("3333333", left.get(2))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("3333333", left.get(2))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("3333333", left.get(2))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("3333333", left.get(2))));

    right.add(new ScrollBean(true, left.get(3)));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("4444444", left.get(3))));

    right.add(new ScrollBean(true, left.get(4)));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("5555555", left.get(4))));

    right.add(new ScrollBean(true, left.get(5)));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("6666666", left.get(5))));

    right.add(new ScrollBean(true, left.get(6)));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("7777777", left.get(6))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("7777777", left.get(6))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("7777777", left.get(6))));
    right.add(new ScrollBean(new ScrollBean.ScrollItemBean("7777777", left.get(6))));

    for (int i = 0; i < right.size(); i++) {
        if (right.get(i).isHeader) {
            //遍歷右側(cè)列表,判斷如果是header,則將此header在右側(cè)列表中所在的position添加到集合中
            tPosition.add(i);
        }
    }
}

首先是左側(cè)列表的數(shù)據(jù)集桅锄,很簡單琉雳,只是一個String類型的list集合。而右側(cè)列表有人看了可能會懵友瘤,這個是我為什么想讓大家看了上面那個adapter庫之后再看這篇文章的原因翠肘,右側(cè)的數(shù)據(jù)格式是brvah專門應(yīng)對這種情況而定義的一種數(shù)據(jù)格式。簡單來說商佑,每一組中間我都空著一行來區(qū)分锯茄,每一組的第一條數(shù)據(jù)(也就是那行短的)是右側(cè)組名的數(shù)據(jù),其余等長的則是每一組的item數(shù)據(jù)茶没。組名的先不說肌幽,單說item的bean,里面有兩個參數(shù)抓半,一個是String類型的文本內(nèi)容喂急,一個是區(qū)分分組的String類型的type。代碼如下:

public static class ScrollItemBean {
    private String text;
    private String type;

    public ScrollItemBean(String text, String type) {
        this.text = text;
        this.type = type;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

然后在最下面有一個循環(huán)笛求,遍歷右側(cè)數(shù)據(jù)集合廊移,將右側(cè)組名所在的position拿出來存在一個集合中(此position用來點擊左側(cè)列表然后定位右側(cè)列表位置的,當(dāng)中妙處探入,不必多言狡孔,請往下看)。
可能大家都注意到了蜂嗽,右側(cè)有一個分類的title懸停在列表之上苗膝,那下一步就從這里開始。
首先是構(gòu)建adapter以及給右側(cè)初始化一些數(shù)據(jù):

rightManager = new GridLayoutManager(mContext, 3);

if (rightAdapter == null) {
    rightAdapter = new ScrollRightAdapter(R.layout.scroll_right, R.layout.layout_right_title, null);
    recRight.setLayoutManager(rightManager);
    recRight.addItemDecoration(new RecyclerView.ItemDecoration() {
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            outRect.set(dpToPx(mContext, getDimens(mContext, R.dimen.dp3))
                    , 0
                    , dpToPx(mContext, getDimens(mContext, R.dimen.dp3))
                    , dpToPx(mContext, getDimens(mContext, R.dimen.dp3)));
        }
    });
        recRight.setAdapter(rightAdapter);
} else {
    rightAdapter.notifyDataSetChanged();
}

rightAdapter.setNewData(right);

//設(shè)置右側(cè)初始title
if (right.get(first).isHeader) {
    rightTitle.setText(right.get(first).header);
}

解釋一波植旧,setNewData()是adapter庫中自帶的一個方法辱揭,也就是給adapter添加數(shù)據(jù)离唐,此處不提。下面一個方法问窃,是給右側(cè)列表上方懸停title設(shè)置初始數(shù)據(jù)的亥鬓,其中有一個成員變量:first,這個參數(shù)是一個int類型的數(shù)值域庇,記錄右側(cè)列表中可見的第一個item的position嵌戈。first我抽取了一個成員變量,并且給了一個默認(rèn)值0听皿。

//記錄右側(cè)當(dāng)前可見的第一個item的position
private int first = 0;

再看看new Adapter里面的兩個布局咕别,相信您看完上面的鏈接,就會知道:前一個布局文件是右側(cè)列表item的布局(紅)写穴,后面一個布局則是右側(cè)列表分類title的布局(綠)。對應(yīng)位置見下圖:


重點

右側(cè)的初始化工作完成之后雌贱,就來到了本文的重點部分啊送,也就是監(jiān)聽右側(cè)列表的滑動。添加一個監(jiān)聽:recRight.addOnScrollListener()欣孤。里面重寫兩個方法:onScrollStateChanged()和onScrolled()馋没。

首先來看onScrollStateChanged()拱镐,里面只有一句:

@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    //獲取右側(cè)title的高度
    tHeight = rightTitle.getHeight();
}

然后我們再看onScrolled()位衩,幾乎所有的重點代碼都在這個方法里面,所以我就拆開一步一步分析(代碼中基本每一句都有注釋糠聪,所以在文章中就不過多的解釋了):

1.先是右側(cè)頂部title設(shè)置偏移量的方法(右側(cè)當(dāng)前顯示哪一組婆排,頂部title就顯示該組名):

//判斷如果是組名的item
if (right.get(first).isHeader) {
    //獲取此組名item的view
    View view = rightManager.findViewByPosition(first);
    if (view != null) {
        //如果此組名item頂部和父容器頂部距離大于等于title的高度,則設(shè)置偏移量
        if (view.getTop() >= tHeight) {
            rightTitle.setY(view.getTop() - tHeight);
        } else {
            //否則不設(shè)置
            rightTitle.setY(0);
        }
    }    
}

2.title的偏移量處理完了之后声旺,就是title賦值的問題了:

//因為每次滑動之后,右側(cè)列表中可見的第一個item的position肯定會改變,并且右側(cè)列表中可見的第一個item的position變換了之后//,才有可能改變右側(cè)title的值,所以這個方法內(nèi)的邏輯在右側(cè)可見的第一個item的position改變之后一定會執(zhí)行
int firstPosition = rightManager.findFirstVisibleItemPosition();
if (first != firstPosition && firstPosition >= 0) {
    //給first賦值
    first = firstPosition;
    //不設(shè)置Y軸的偏移量
    rightTitle.setY(0);

    //判斷如果右側(cè)可見的第一個item是否是header,設(shè)置相應(yīng)的值
    if (right.get(first).isHeader) {
        rightTitle.setText(right.get(first).header);
    } else {
        rightTitle.setText(right.get(first).t.getType());
    }
}

3.title的賦值問題之后,是與左側(cè)關(guān)聯(lián)的方法:

//遍歷左邊列表,列表對應(yīng)的內(nèi)容等于右邊的title,則設(shè)置左側(cè)對應(yīng)item高亮
for (int i = 0; i < left.size(); i++) {
    if (left.get(i).equals(rightTitle.getText().toString())) {
        leftAdapter.selectItem(i);
    }
}

4.最后就是一些細(xì)節(jié)上面的處理了:

//如果右邊最后一個完全顯示的item的position,等于bean中最后一條數(shù)據(jù)的position(也就是右側(cè)列表拉到底了),
//則設(shè)置左側(cè)列表最后一條item高亮
if (rightManager.findLastCompletelyVisibleItemPosition() == right.size() - 1) {
    leftAdapter.selectItem(left.size() - 1);
}

右側(cè)Adapter也沒有什么可看的段只,就是brvah中封裝的一個adapter腮猖,里面只是給右側(cè)組名和item賦值而已,附上代碼:

public class ScrollRightAdapter extends BaseSectionQuickAdapter<ScrollBean, BaseViewHolder> {

    public ScrollRightAdapter(int layoutResId, int sectionHeadResId, List<ScrollBean> data) {
        super(layoutResId, sectionHeadResId, data);
    }

    @Override
    protected void convertHead(BaseViewHolder helper, ScrollBean item) {
        helper.setText(R.id.right_title, item.header);
    }

    @Override
    protected void convert(BaseViewHolder helper, ScrollBean item) {
        ScrollBean.ScrollItemBean t = item.t;
        helper.setText(R.id.right_text, t.getText());
    }
}

至此為止赞枕,右側(cè)列表的處理澈缺,也就是本文中最重要的一部分已經(jīng)都結(jié)束了,那我們再來看看左側(cè)列表吧炕婶。由于左側(cè)的處理只是點擊姐赡,所以除了初始化左側(cè)RecyclerView之外,只有一個點擊事件柠掂,代碼如下:

private void initLeft() {
    if (leftAdapter == null) {
        leftAdapter = new ScrollLeftAdapter(R.layout.scroll_left, null);
        recLeft.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false));
        recLeft.addItemDecoration(new DividerItemDecoration(mContext, DividerItemDecoration.VERTICAL));
        recLeft.setAdapter(leftAdapter);
    } else {
        leftAdapter.notifyDataSetChanged();
    }

    leftAdapter.setNewData(left);

    leftAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
        @Override
        public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
            switch (view.getId()) {
                //點擊左側(cè)列表的相應(yīng)item,右側(cè)列表相應(yīng)的title置頂顯示
                //(最后一組內(nèi)容若不能填充右側(cè)整個可見頁面,則顯示到右側(cè)列表的最底端)
                case R.id.item:
                    leftAdapter.selectItem(position);
                    rightManager.scrollToPositionWithOffset(tPosition.get(position), 0);
                    break;
            }
        }
    });
}

這就是左側(cè)RecyclerView的初始化以及聯(lián)動的處理方法项滑,最后看一看左側(cè)adapter吧:

public class ScrollLeftAdapter extends BaseQuickAdapter<String, BaseViewHolder> {

    private List<TextView> tv = new ArrayList<>();

    public ScrollLeftAdapter(int layoutResId, @Nullable List<String> data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, String item) {
        helper.setText(R.id.left_text, item)
                .addOnClickListener(R.id.item);
        //將左側(cè)item中的TextView添加到集合中
        tv.add((TextView) helper.getView(R.id.left_text));
        //設(shè)置進入頁面之后,左邊列表的初始狀態(tài)
        if (tv != null && getData() != null && tv.size() == getData().size()) {
            selectItem(0);
        }

        helper.getView(R.id.item).setSelected(true);
    }
}

這里面有一個selectItem(),這個也就是本文最后一個需要注意的地方了陪踩,此方法是右側(cè)列表滑動杖们,左側(cè)跟著聯(lián)動的一個方法悉抵。使用此方法需要傳一個參數(shù),這個position是右側(cè)組名所對應(yīng)的position(知道上面為何要循環(huán)取出右側(cè)列表組名所對應(yīng)的position了吧)摘完。附上代碼:

//傳入position,設(shè)置左側(cè)列表相應(yīng)item高亮
public void selectItem(int position) {
    for (int i = 0; i < getData().size(); i++) {
        if (position == i) {
            tv.get(i).setBackgroundColor(0xff0068b7);
            tv.get(i).setTextColor(ContextCompat.getColor(mContext, R.color.white));

            //以下是指定某一個TextView滾動的效果
            tv.get(i).setEllipsize(TextUtils.TruncateAt.MARQUEE);
            tv.get(i).setFocusable(true);
            tv.get(i).setFocusableInTouchMode(true);
            tv.get(i).setMarqueeRepeatLimit(-1);
        } else {
            tv.get(i).setBackgroundColor(0xffffffff);
            tv.get(i).setTextColor(ContextCompat.getColor(mContext, R.color.black));

            //失去焦點則停止?jié)L動
            tv.get(i).setEllipsize(TextUtils.TruncateAt.END);
            tv.get(i).setFocusable(false);
            tv.get(i).setFocusableInTouchMode(false);
            tv.get(i).setMarqueeRepeatLimit(0);
        }
    }
}

判斷方法中姥饰,前兩行是對應(yīng)item的背景和字體顏色的改變,下面四行孝治,是一個跑馬燈的效果(左側(cè)item中列粪,我設(shè)置了只顯示一行,對應(yīng)的item中的內(nèi)容如果顯示不下谈飒,則無限滾動顯示)岂座。

結(jié)尾

好了,demo中比較重要的方法我都羅列出來了杭措,也貼出了相應(yīng)的代碼费什,最后還是忍不住推薦一下這個adapter庫:BaseRecyclerViewAdapterHelper,這個庫真的是太好用了手素,我現(xiàn)在幾乎所有的項目包括本篇文章涉及到的內(nèi)容鸳址,都在用這個,強烈推薦H场8迨颉!最后附上demo崩哩,希望可以幫到大家巡球。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市邓嘹,隨后出現(xiàn)的幾起案子酣栈,更是在濱河造成了極大的恐慌,老刑警劉巖汹押,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钉嘹,死亡現(xiàn)場離奇詭異,居然都是意外死亡鲸阻,警方通過查閱死者的電腦和手機跋涣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸟悴,“玉大人陈辱,你說我怎么就攤上這事∠钢睿” “怎么了沛贪?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我利赋,道長水评,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任媚送,我火速辦了婚禮中燥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘塘偎。我一直安慰自己疗涉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布吟秩。 她就那樣靜靜地躺著咱扣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涵防。 梳的紋絲不亂的頭發(fā)上闹伪,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音壮池,去河邊找鬼祭往。 笑死,一個胖子當(dāng)著我的面吹牛火窒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播驮肉,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼熏矿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了离钝?” 一聲冷哼從身側(cè)響起票编,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卵渴,沒想到半個月后慧域,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡浪读,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年昔榴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碘橘。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡互订,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出痘拆,到底是詐尸還是另有隱情仰禽,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站吐葵,受9級特大地震影響规揪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜温峭,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一猛铅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诚镰,春花似錦奕坟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至抠艾,卻和暖如春苛萎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背检号。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工腌歉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人齐苛。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓翘盖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親凹蜂。 傳聞我的和親對象是個殘疾皇子馍驯,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355