AndroidJetPack組件 - Navigation使用

Navigation

Navigation是google官方新增的用于Fragment管理的一個架構(gòu)組件,可以很方便的像管理Activity一樣管理你的Fragment,并且google在AndroidStudio3.2中加入了可視化手動拖拽式的組件

基本概念

  • App - 一個頁面棧結(jié)構(gòu)
  • Destination - 一個頁面的子頁面,通常是一個Fragment,但也支持其他類型
    1. Activity
    2. 其他NavigationGraph
    3. 自定義Destination
  • Deep-Link - 鏈接形式的跳轉(zhuǎn)(URI形式的鏈接)
  • NavigationGraph - 一組Destination構(gòu)成的頁面結(jié)構(gòu)(一個Navigation xml文件表示)
  • Actions - 連接不同Destination的行為

Navigation的編寫原則

  • 每個App必須有個固定的起點,對應(yīng)的,每個Activity中也需要有個固定的起點Fragment
  • 使用Stack結(jié)構(gòu)來管理Navigation狀態(tài),起始頁面在Stack底部,當前頁面在Stack的top,在Navigation中使用destination來描述一個頁面,可以是Activity也可以是Fragment
  • 開始destination不顯示上一頁按鈕,如果是從其他App頁面通過deep-link(下面會講到)導(dǎo)航過來的,按上一頁返回的是父級頁面而不是其他App
  • Back和Up(上一頁)在大部分情況下是等同的,除非Back按鈕按下后會使得App退出
  • Deep-link 和 普通Navigation 跳轉(zhuǎn)形成的頁面棧應(yīng)該是一樣的

Navigation簡單例子的編寫步驟

1.有一個Activity,在layout文件中聲明一個fragment

  <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.apm29.yjw.demo.ui.main.MainActivity">
    <fragment
        android:layout_width="match_parent"
        android:id="@+id/my_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/main_nav_graph"
        app:defaultNavHost="true"
        android:layout_height="match_parent"/>
</FrameLayout>

當然Navigation也提供了代碼式的引入形式

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

2.編寫main_nav_graph.xml文件(文件名自己定義)

<?xml version="1.0" encoding="utf-8"?>
<navigation 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"
    app:startDestination="@id/mainFragment">

    <fragment
        android:id="@+id/mainFragment"
        android:name="com.apm29.yjw.demo.ui.main.MainFragment"
        android:label="MainFragment">
        <action
            android:id="@+id/action_mainFragment_to_mainDetailFragment"
            app:destination="@id/mainDetailFragment" />
    </fragment>
    <fragment
        android:id="@+id/mainDetailFragment"
        android:name="com.apm29.yjw.demo.ui.main.MainDetailFragment"
        android:label="MainDetailFragment">
        <argument android:name="id"
            app:argType="String"
            android:defaultValue="0"/>
        <deepLink
            android:autoVerify="true"
            app:uri="www.main.detail/{id}" />
    </fragment>
</navigation>
  • app:startDestination="@id/mainFragment" 指定初始頁面
  • fragment節(jié)點表示一個destination
  • name屬性指定Fragment的全路徑名
  • label是在可視化界面的顯示名稱
  • action標簽定義了Destination之間的跳轉(zhuǎn)行為
  1. 將Navigation綁定到UI組件

其中有一個關(guān)鍵的類NavController,通過以下方法得到其實例

  • NavHostFragment.findNavController(Fragment)
  • Navigation.findNavController(Activity, @IdRes int viewId)
  • Navigation.findNavController(View)

然后使用它的navigate方法導(dǎo)航到你想去的Destination,接收參數(shù)可以是一個ActionId(定義在nav_graph文件中的),使用navigateUp,popBackStack對應(yīng)Up和Back按鍵,另外還可以加入Bundle,NavOption,ShareElements等,參考https://developer.android.google.cn/topic/libraries/architecture/navigation/navigation-implementing#Create-transition

// Rename the Pair class from the Android framework to avoid a name clash
import android.util.Pair as UtilPair
...
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
        UtilPair.create(imageView, "header_image"),
        UtilPair.create(titleView, "header_title"))
val extras = ActivityNavigator.Extras(options)
view.findNavController().navigate(R.id.details,
    null, // Bundle of args
    null, // NavOptions
    extras)

使用SharedElement

val extras = FragmentNavigatorExtras(
    imageView to "header_image",
    titleView to "header_title")
view.findNavController().navigate(R.id.confirmationAction,
    null, // Bundle of args
    null, // NavOptions
    extras)

先給navigate()方法添加extra參數(shù),包含了一些<View,String>的Pair,View表示sharedElement,String則是transitionName,可以在xml中確定也可以代碼確定

<ImageView
        android:transitionName="@string/app_icon"
        android:id="@+id/imageView"
        app:srcCompat="@mipmap/ic_launcher_round" />
imageView.transitionName = getString(R.string.app_icon)

然后再設(shè)置Fragment中的SharedElementReturnTransition和SharedElementEnterTransition

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            sharedElementReturnTransition = AutoTransition()
            sharedElementEnterTransition = AutoTransition()
 }

實際上Navigation 1.0.0 alpha06才加入的這個功能,并不是很完善,只為我們完成了SharedELement的添加,剩余工作還是我們自己完成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桂对,一起剝皮案震驚了整個濱河市熙侍,隨后出現(xiàn)的幾起案子仿贬,更是在濱河造成了極大的恐慌恕刘,老刑警劉巖渠旁,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件误甚,死亡現(xiàn)場離奇詭異埋同,居然都是意外死亡琼锋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門胀糜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颅拦,“玉大人,你說我怎么就攤上這事教藻【嗨В” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵括堤,是天一觀的道長碌秸。 經(jīng)常有香客問我,道長悄窃,這世上最難降的妖魔是什么讥电? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮轧抗,結(jié)果婚禮上恩敌,老公的妹妹穿的比我還像新娘。我一直安慰自己横媚,他們只是感情好纠炮,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著灯蝴,像睡著了一般恢口。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上穷躁,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天耕肩,我揣著相機與錄音,去河邊找鬼。 笑死看疗,一個胖子當著我的面吹牛沙峻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播两芳,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼摔寨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了怖辆?” 一聲冷哼從身側(cè)響起是复,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竖螃,沒想到半個月后淑廊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡特咆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年季惩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腻格。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡画拾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出菜职,到底是詐尸還是另有隱情青抛,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布酬核,位于F島的核電站蜜另,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏嫡意。R本人自食惡果不足惜举瑰,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鹅很。 院中可真熱鬧嘶居,春花似錦、人聲如沸促煮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽菠齿。三九已至,卻和暖如春坐昙,著一層夾襖步出監(jiān)牢的瞬間绳匀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疾棵,地道東北人戈钢。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像是尔,于是被迫代替她去往敵國和親殉了。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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