【譯】Android Jetpack 架構(gòu)導(dǎo)航組件之Navigation

示例代碼:android-navigation
介紹:Navigation Codelab
原文:navigation-implementing

導(dǎo)航架構(gòu)組件簡(jiǎn)化了App內(nèi)不同目標(biāo)的導(dǎo)航實(shí)現(xiàn)黎棠。一個(gè)目標(biāo)即是App內(nèi)一個(gè)特定的屏幕晋渺。導(dǎo)航架構(gòu)組件默認(rèn)包含了對(duì)fragments和Activities的支持,但是你也可以添加對(duì)新類型目標(biāo)的支持脓斩。一系列的目標(biāo)集合組成了app的導(dǎo)航圖木西。

另外,導(dǎo)航圖內(nèi)不同目標(biāo)的連接被稱作"actions"随静。圖1展示了示例app內(nèi)一個(gè)假設(shè)的導(dǎo)航圖表現(xiàn)八千,包含了6個(gè)目標(biāo),由5個(gè)actions連接燎猛。

圖1 navigation-graph.png

導(dǎo)航架構(gòu)組件是基于Principles of nagivation實(shí)現(xiàn)的恋捆。

Set up nagivation in a project

在你創(chuàng)建一個(gè)導(dǎo)航圖之前,你必須在你的工程內(nèi)配置導(dǎo)航架構(gòu)組件重绷。以下是具體步驟:

  1. 在你的app或者模塊的build.gradle文件內(nèi)天井Navigation Architecture Component沸停。點(diǎn)擊Adding components to your project查看更多。
  2. 在工程窗口昭卓,右擊 res 目錄愤钾,選擇 New > Android resource file。顯示New Resource對(duì)話框候醒。
  3. 輸入資源名稱在File name欄目能颁,比如“nav_graph”。
  4. 選擇NavigationResource type下拉列表倒淫。
  5. 點(diǎn)擊 OK伙菊。出現(xiàn)以下項(xiàng)目:
    a. 一個(gè) nagivation 資源目錄在res目錄下創(chuàng)建。
    b. 一個(gè)nav_graph.xml文件在navigation目錄下創(chuàng)建昌简。
    c. nav_graph.xml文件將在Navigation Editor中打開。這個(gè)文件包含了你的導(dǎo)航圖绒怨。
  6. 點(diǎn)擊Texttab可以打開或者關(guān)閉text View纯赎。空導(dǎo)航圖如下:

<?xml version="1.0" encoding="utf-8"?><navigation xmlns:android="http://schemas.android.com/apk/res/android"></navigation>

  1. 點(diǎn)擊 Design返回導(dǎo)航編輯器南蹂。

Tour The Navigation Editor

Note: The Navigation Editor是在Android Studio的Canary Build中默認(rèn)開啟的犬金。為了在Beta,Release Candidate和Stable Builds 中啟用,在Mac上點(diǎn)擊File > Settings(Android Studio > Preferences)晚顷,在左側(cè)面板選擇Experimentalcategory峰伙,選擇Enable Navigation Editor,最后重啟Android Studio该默。

圖2 navigation-editor.png

在導(dǎo)航編輯器瞳氓,你可以快速地構(gòu)建導(dǎo)航圖,不需要手動(dòng)構(gòu)建graph’s xml文件栓袖。按照圖2顯示的匣摘,導(dǎo)航編輯器分為三個(gè)部分。
1. 目標(biāo)列表-羅列當(dāng)前導(dǎo)航編輯器內(nèi)所有目標(biāo)裹刮。
2. 圖編輯器-包含導(dǎo)航圖內(nèi)所有虛擬目標(biāo)音榜。
3. 屬性編輯器-包含目標(biāo)屬性和導(dǎo)航圖內(nèi)的actions。

Identify destinations

為你的app驗(yàn)證目標(biāo)是創(chuàng)建導(dǎo)航圖的第一部捧弃。你可以創(chuàng)建一個(gè)空目標(biāo)或者在一個(gè)已經(jīng)存在的工程內(nèi)為fragments和Acitvities創(chuàng)建目標(biāo)赠叼。

Note:導(dǎo)航架構(gòu)組件是為一個(gè)activity內(nèi)包含多個(gè)fragment的場(chǎng)景而設(shè)計(jì)的。主activity擁有導(dǎo)航圖违霞。在一個(gè)擁有眾多activity目標(biāo)的app內(nèi)嘴办,每一個(gè)附加的activity都擁有自己的導(dǎo)航圖。修改一個(gè)activity到主導(dǎo)航將在之后的文檔進(jìn)行討論葛家。

請(qǐng)參照一下步驟驗(yàn)證app內(nèi)目標(biāo):

  1. 在圖編輯器户辞,點(diǎn)擊** New DestinationNew Destination** 顯示癞谒。
  2. 點(diǎn)擊Create blank destination或者點(diǎn)擊一個(gè)fragment或者activity底燎。會(huì)出現(xiàn)新的Android Component 對(duì)話框。
  3. Fragment Name字段輸入名字弹砚。這個(gè)名字是fragment的類的名字双仍。
  4. Fragment layout Name字段輸入一個(gè)名字。這個(gè)名字是fragment布局文件的名字桌吃。
  5. 點(diǎn)擊完成朱沃,在圖標(biāo)編輯器的目標(biāo)列表出現(xiàn)一個(gè)目標(biāo),出現(xiàn)以下現(xiàn)象:
  • 如果你創(chuàng)建一個(gè)空白的目標(biāo)茅诱,在圖標(biāo)編輯器出現(xiàn)一個(gè)空白的一個(gè)“Hello blank fragment” 的信息的目標(biāo)逗物,如果你點(diǎn)擊了一個(gè)Fragment或者Activity,圖標(biāo)編輯器會(huì)顯示對(duì)應(yīng)的布局瑟俭。
  • 一個(gè)fragment子類將會(huì)被創(chuàng)建翎卓,名字在第三步被指定。
  • 一個(gè)資源文件會(huì)被創(chuàng)建摆寄,名字在第四步被指定失暴。

圖3 展示了一個(gè)空白的已經(jīng)存在的目標(biāo)坯门。


圖3 navigation-newexisting.png
  1. 點(diǎn)擊高亮顯示新插入的目標(biāo)。在屬性面板顯示以下屬性逗扒。
  • 在類型字段顯示“fragment”或者“activity”古戴,表示目標(biāo)是否執(zhí)行了fragment或者activity。
  • 標(biāo)簽字段表示了目標(biāo)布局文件的名字矩肩;
  • ID字段表示了目標(biāo)的ID现恼,用來在代碼中被引用;
  • 類字段表示了引用的目標(biāo)的類名蛮拔;
  1. 點(diǎn)擊Text 進(jìn)入xml視圖述暂,XML現(xiàn)在包含id,name(class name)建炫,label和layout屬性畦韭,基于已經(jīng)存在的類和布局文件的名字。
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/blankFragment">
    <fragment
        android:id="@+id/blankFragment"
        android:name="com.example.cashdog.cashdog.BlankFragment"
        android:label="Blank"
        tools:layout="@layout/fragment_blank" />
</navigation>

Note:XML布局startDestination 表示一個(gè)空目標(biāo)的Id肛跌,(app:startDestination="@+id/fragment")艺配。查詢更多關(guān)于startDestination信息請(qǐng)點(diǎn)擊 Designate a screen as the start destination

Connect destinations

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/blankFragment">
    <fragment
        android:id="@+id/blankFragment"
        android:name="com.example.cashdog.cashdog.BlankFragment"
        android:label="fragment_blank"
        tools:layout="@layout/fragment_blank" />
    <fragment
        android:id="@+id/blankFragment2"
        android:name="com.example.cashdog.cashdog.BlankFragment2"
        android:label="Blank2"
        tools:layout="@layout/fragment_blank_fragment2" />
</navigation>

通過action連接不同的destination:
1衍慎、在Graph Editor转唉,當(dāng)鼠標(biāo)浮動(dòng)在destination的右邊緣時(shí)會(huì)顯示一個(gè)圈;
2稳捆、點(diǎn)擊并且拖動(dòng)圓圈到另一個(gè)destination赠法,一條線將會(huì)關(guān)聯(lián)起兩個(gè)destination;


圖5navigation-connected.png

3乔夯、點(diǎn)擊高亮箭頭砖织,屬性面板顯示以下屬性:

  • 類型字段包含“Action”;
  • ID字段表示了系統(tǒng)為action指定的ID末荐;
  • Destination字段表示了目標(biāo)Activity或者Fragment侧纯;
    4、代碼展示:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/blankFragment">
    <fragment
        android:id="@+id/blankFragment"
        android:name="com.example.cashdog.cashdog.BlankFragment"
        android:label="fragment_blank"
        tools:layout="@layout/fragment_blank" >
        <action
            android:id="@+id/action_blankFragment_to_blankFragment2"
            app:destination="@id/blankFragment2" />
    </fragment>
    <fragment
        android:id="@+id/blankFragment2"
        android:name="com.example.cashdog.cashdog.BlankFragment2"
        android:label="fragment_blank_fragment2"
        tools:layout="@layout/fragment_blank_fragment2" />
</navigation>

Designate a screen as the start destination

Graph Editor中甲脏,進(jìn)入app的第一個(gè)Destination會(huì)有一個(gè)house的icon眶熬。通過一下步驟可以將另外一個(gè)Destination指定為啟動(dòng)Destination。
1块请、點(diǎn)擊高亮顯示某個(gè)Destination娜氏;
2、點(diǎn)擊屬性面板的Set Start Destination即可完成設(shè)置墩新;

Modify an activity to host navigation

一個(gè)Activity通過NavHost的實(shí)現(xiàn)類來持有app的導(dǎo)航贸弥。NavHost是一個(gè)空的View,因此Destinations會(huì)根據(jù)用戶的導(dǎo)航被交換進(jìn)或者退出抖棘。
Navigation Architecture Component 的默認(rèn)的NavHost的實(shí)現(xiàn)是NavHostFragment茂腥。
在你包含了NavHost之后,你必須使用navGraph屬性將NavHostFragment和Navigation graph關(guān)聯(lián)起來切省。下面是代碼示例:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/my_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true"
        />

</android.support.constraint.ConstraintLayout>

上述例子的app:defaultNavHost="true"屬性可以確保NavHostFragment可以攔截系統(tǒng)的回退事件最岗。你也可以重寫AppCompatActivity.onSupportNavigateUp()方法并且調(diào)用NavController.navigateUp方法:

@Override
public boolean onSupportNavigateUp() {
    return Navigation.findNavController(this, R.id.nav_host_fragment).navigateUp();
}

Create the NavHostFragment programmatically

你可以使用NavHostFragment.create()
編碼創(chuàng)建NavHostFragment ,關(guān)聯(lián)一個(gè)graph資源朝捆,如下所示:

NavHostFragment finalHost = NavHostFragment.create(R.navigation.example_graph);
getSupportFragmentManager().beginTransaction()
    .replace(R.id.nav_host, finalHost)
    .setPrimaryNavigationFragment(finalHost) // this is the equivalent to app:defaultNavHost="true"
    .commit();

Tie destinations to UI widgets

通過NavController
實(shí)現(xiàn)對(duì)Destination的導(dǎo)航般渡。通過以下靜態(tài)方法獲取NavController示例:

viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
    }
});

Android 系統(tǒng)維護(hù)了一個(gè)back stack來表示最近訪問的destination。
在app啟動(dòng)得時(shí)候驮樊,第一個(gè)destination會(huì)被放入棧里面薇正。每一次調(diào)用navigate()
都會(huì)放入另外一個(gè)destination在棧的頂部。相反的囚衔,調(diào)用NavController.navigateUp()
NavController.popBackStack()
方法挖腰,從棧里彈出頂部的destination。對(duì)于按鈕练湿,你可以使用Navigation
類的 createNavigateOnClickListener() 方法來很方便地去導(dǎo)航到destination猴仑。

button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null));

Tie destinations to menu-driven UI components

通過為destination、navigation drawer和overflow menu設(shè)置相同的Id來將destination和navigation drawer或者overflow menu關(guān)聯(lián)起來肥哎。以下代碼片段顯示了id為details_page_fragment的destination:

<fragment android:id="@+id/details_page_fragment"
     android:label="@string/details"
     android:name="com.example.android.myapp.DetailsFragment" />

以下代碼片段表示了如何關(guān)聯(lián)fragment destination 和navigation drawer中的menu item辽俗,比如( menu_nav_drawer.xml)。

<item
   android:id="@id/details_page_fragment"
   android:icon="@drawable/ic_details"
   android:title="@string/details" />

以下XML表示了如果把destination和overflow menu 關(guān)聯(lián)的細(xì)節(jié):

<item
    android:id="@id/details_page_fragment"
    android:icon="@drawable/ic_details"
    android:title="@string/details"
    android:menuCategory:"secondary" />

Navigation Architecture Component 包含了一個(gè)NavigationUI
類贤姆。這個(gè)類的多個(gè)靜態(tài)方法都可以用來關(guān)聯(lián) menu item 和 navigation destination榆苞。以下代碼表示了如果使用setupWithNavController()
方法去關(guān)聯(lián) menu item 到Navigation View。

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
NavigationUI.setupWithNavController(navigationView, navController);

使用NavigationUI
去設(shè)置menu 驅(qū)動(dòng)的導(dǎo)航組件是很有必要的霞捡,因?yàn)檫@樣可以同步這些UI元素地改變到NavController坐漏。

Pass data between destinations

兩種方式在不同的destination之間傳遞數(shù)據(jù):使用Bundle
對(duì)象或者通過Gradle插件類型安全得傳遞數(shù)據(jù)。遵照以下步驟在destinations之間使用Bundle對(duì)象傳遞數(shù)據(jù)碧信。如果你想使用Gradle赊琳,請(qǐng)遵照Pass data between destinations in a type-safe way
的介紹越除。
1镰惦、在Graph Editor,點(diǎn)擊接受參數(shù)的destination专肪。該destination會(huì)高亮呈枉。
2趁尼、在屬性面板的參數(shù)部分點(diǎn)擊 Add(+)埃碱,會(huì)顯示空名字和默認(rèn)值字段。
3酥泞、在名字字段雙擊輸入?yún)?shù)名字砚殿。
4、按壓Tab芝囤,輸入?yún)?shù)的默認(rèn)值似炎。
5、點(diǎn)擊上述destination的action悯姊。參數(shù)的默認(rèn)值應(yīng)該包含你新增的參數(shù)羡藐。
6、點(diǎn)擊Text去切換XML View悯许。一個(gè)參數(shù)元素仆嗦,包含名字和默認(rèn)值屬性,已經(jīng)被添加到該destination先壕。

<fragment
  android:id="@+id/confirmationFragment"
  android:name="com.example.buybuddy.buybuddy.ConfirmationFragment"
  android:label="fragment_confirmation"
  tools:layout="@layout/fragment_confirmation">
  <argument android:name="amount" android:defaultValue="1" app:type="integer"/>
</fragment>

當(dāng)你使用safeargs plugin欧啤,會(huì)為action,destinations的接受者和發(fā)送者創(chuàng)建簡(jiǎn)單對(duì)象和構(gòu)造類启上。這些類是:

  • 一個(gè)類為action源起的destination邢隧,后綴“Directions”。因此冈在,如果起始的fragment叫做SpecifyAmountFragment倒慧,那么生成的類就叫做SpecifyAmountFragmentDirections。這個(gè)類有一個(gè)以傳遞參數(shù)的action來命名包券,去綁定參數(shù)纫谅,比如confirmationAction()。
  • 一個(gè)匿名內(nèi)部類溅固,名字基于傳遞參數(shù)的action付秕。如果傳遞的action叫做confirmationAction,類就被命名為ConfirmationAciton侍郭。
  • 一個(gè)類用于接受destination询吴,后綴Args,所以亮元,如果destination fragment叫做ComfirmationFragment猛计,生成的類就叫做ConfirmationFragmentArgs。使用這個(gè)類的fromBundle()方法獲取參數(shù)爆捞。
    示例代碼:
@Override
public void onClick(View view) {
  EditText amountTv = (EditText) getView().findViewById(R.id.editTextAmount);
  int amount = Integer.parseInt(amountTv.getText().toString());
  ConfirmationAction action =
          SpecifyAmountFragmentDirections.confirmationAction()
  action.setAmount(amount)
  Navigation.findNavController(view).navigate(action);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    TextView tv = view.findViewById(R.id.textViewAmount);
    int amount = ConfirmationFragmentArgs.fromBundle(getArguments()).getAmount();
    tv.setText(amount + "")
}

Group destinations into a nested navigation graph

在navigation graph內(nèi)奉瘤,可以把一些相關(guān)的destination是分組為sub-graph,如果包含sub-graph的是root-graph煮甥,那么這個(gè)sub-graph被稱作“nestedgraph”盗温,Nestedgraph在組織和重用App UI的模塊上是很有用的藕赞,比如登錄流程。
和root graph一樣卖局,nested graph必須也要有一個(gè)啟動(dòng)的destination作為唯一的標(biāo)識(shí)找默。nested graph封裝了它的destinations。nested graph外部吼驶,root graph之內(nèi)的destination只能通過root graph的啟動(dòng)destination訪問nested graph。圖6 展示了一個(gè)simple money transfer app的navigation graph店煞。這個(gè)graph有兩個(gè)流程:轉(zhuǎn)錢流程和余額流程蟹演。

圖6 navigation-pre-nestedgraph.png

把destinations分組為nested graph:
1、在graph editor顷蟀,按住shift點(diǎn)擊需要加入nested graph的destination酒请,該destination高亮。
2鸣个、打開菜單選擇Move to Nested Graph > New Graph羞反,如圖7.
圖7navigation-nestedgraph.png

3、點(diǎn)擊高亮nested graph囤萤,屬性面板顯示如下:

  • Type字段顯示“Nested Graph”昼窗。
  • Id字段是系統(tǒng)為nested graph指定的。Id用來在代碼中引用這個(gè)nested graph涛舍。
    4澄惊、雙擊nested graph查看內(nèi)部的destinations。
    5富雅、在destinations列表掸驱,點(diǎn)擊root返回root graph。
    6没佑、點(diǎn)擊Text進(jìn)入XML視圖毕贼。
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   xmlns:android="http://schemas.android.com/apk/res/android"
   app:startDestination="@id/mainFragment">
   <fragment
       android:id="@+id/mainFragment"
       android:name="com.example.cashdog.cashdog.MainFragment"
       android:label="fragment_main"
       tools:layout="@layout/fragment_main" >
       <action
           android:id="@+id/action_mainFragment_to_chooseRecipient"
           app:destination="@id/sendMoneyGraph" />
       <action
           android:id="@+id/action_mainFragment_to_viewBalanceFragment"
           app:destination="@id/viewBalanceFragment" />
   </fragment>
   <fragment
       android:id="@+id/viewBalanceFragment"
       android:name="com.example.cashdog.cashdog.ViewBalanceFragment"
       android:label="fragment_view_balance"
       tools:layout="@layout/fragment_view_balance" />
   <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient">
       <fragment
           android:id="@+id/chooseRecipient"
           android:name="com.example.cashdog.cashdog.ChooseRecipient"
           android:label="fragment_choose_recipient"
           tools:layout="@layout/fragment_choose_recipient">
           <action
               android:id="@+id/action_chooseRecipient_to_chooseAmountFragment"
               app:destination="@id/chooseAmountFragment" />
       </fragment>
       <fragment
           android:id="@+id/chooseAmountFragment"
           android:name="com.example.cashdog.cashdog.ChooseAmountFragment"
           android:label="fragment_choose_amount"
           tools:layout="@layout/fragment_choose_amount" />
   </navigation>
</navigation>

7、在你的代碼里蛤奢,使用action id來關(guān)聯(lián)root graph 和 nested graph鬼癣。

Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);

Reference other navigation graphs using <include>

在 navigation graph內(nèi),可以通過<include>引用其它navigation graph啤贩,其等價(jià)于使用nested graph扣溺。以此使用其它module或者library中的navigation。

<include app:graph="@navigation/included_graph"/>

<include>只有一個(gè)app:graph屬性瓜晤,且不允許其它任何屬性锥余。

Create a deep link for a destination

Add an intent filter for a deep link

Create a transition between destinations

AndroidX命名空間遷移
Verify Android App Links (Deep Links和Android App Links的區(qū)別)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痢掠,隨后出現(xiàn)的幾起案子驱犹,更是在濱河造成了極大的恐慌嘲恍,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雄驹,死亡現(xiàn)場(chǎng)離奇詭異佃牛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)医舆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門俘侠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔬将,你說我怎么就攤上這事爷速。” “怎么了霞怀?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵惫东,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我毙石,道長(zhǎng)廉沮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任徐矩,我火速辦了婚禮滞时,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滤灯。我一直安慰自己漂洋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布力喷。 她就那樣靜靜地躺著刽漂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪弟孟。 梳的紋絲不亂的頭發(fā)上贝咙,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音拂募,去河邊找鬼庭猩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛陈症,可吹牛的內(nèi)容都是我干的蔼水。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼录肯,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼趴腋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤优炬,失蹤者是張志新(化名)和其女友劉穎颁井,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蠢护,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡雅宾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葵硕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眉抬。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖懈凹,靈堂內(nèi)的尸體忽然破棺而出蜀变,到底是詐尸還是另有隱情,我是刑警寧澤蘸劈,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站尊沸,受9級(jí)特大地震影響威沫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜洼专,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一棒掠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧屁商,春花似錦烟很、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至官还,卻和暖如春芹橡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背望伦。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工林说, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屯伞。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓腿箩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親劣摇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子珠移,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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