1、Android Jetpack_Note_CodeLabs一Navigation

一、簡介

Navigation簡化了導航的實現,同時也幫助您可視化應用程序的導航流,Naviagtion組件提供瞭如下的功能:html

  1. 自動處理Fragment碎片事務
  2. 默認處理返回鍵和上一步的操做
  3. 動畫和過渡的默認行爲
  4. 默認頁面以及下一層的連接操做
  5. 用不多的代碼去實現導航界面(例如導航抽屜和地步導航)
  6. 導航切換界面之間的參數傳遞
  7. 在Android Studio中一個可視化的Navigation操做界面

1.1 你須要作什麼?

Codelab中你可使用demo運行效果:android

全部的Activity和Fragment都已經爲你建立好了,你可使用導航組件鏈接它們,並在鏈接過程當中實現如下功能:git

  1. 一個可視化的Navigation編輯器
  2. 設計導航的目的地和Action
  3. 切換動畫
  4. Menu菜單、底部導航欄以及DrawLayout側邊欄按鈕
  5. 類型安全的參數傳遞
  6. 深層次的連接

1.2 使用條件

  • 基本Kotlin知識(codelab中代碼使用Kotlin)
  • Android Studio 3.2以上
  • API 14+

二、入門

2.1 獲取代碼

Githubgithub

$ git clone https://github.com/googlecodelabs/android-navigation
複製代碼

2.2 Navigation 概述

Navigation組件主要包括三個部分shell

  1. Navigation Graph (一種新版的XML文件),是一個集中包含了全部Navigation相關的信息的一種新版的XML文件。它包括app中的全部界面(Activity或Fragment),以及用戶能夠經過app訪問的可能路徑。
  2. NavHostFragment (Layout XML view),這是一個添加到佈局中的特殊部件。avHostFragment經過navGraph與navigation導航編輯器進行關聯.
  3. NavController(Kotlin/Java object),這是一個跟蹤導航圖中當前位置的對象,當您在導航圖中移動時,它協調交換navhostfragment中的目標內容。

當你導航時,你將使用導航控制器對象,告訴它你想去哪裏,或者你想在你的導航圖中走什麼路徑。而後,導航控制器將在NavHostframent中顯示適當的目的地。編程

這是基本的想法。讓咱們重新的導航圖資源開始,看看這在實踐中是什麼樣子的。設計模式

三、Navigation Graph

3.1 Destinations

Navigation組件中有一個Destinations的概念,它是一個能夠在你APP中導航到的任意的地方,一般是一個Activity或者Fragment,默認是支持使用的,若是你須要你能夠本身自定義目標類型。安全

3.2 Navigation Graph

一個導航圖是一種新的資源類型,它直觀地顯示從給定目的地能夠到達的全部目的地。在AS的Navigation Editor中展現,下面是爲APP建立的起始導航圖的一部分:bash

3.3 Navigation Editor

  1. 打開res/navigation/mobile_navigation.xml文件
  2. 點擊 Desgin 進入設計模式

接下來你能夠看到:

視圖向咱們展現了會用到的目標頁面,視圖中的箭頭咱們叫作 action,下面會詳細介紹

  1. 點擊一個目標界面查看屬性

  1. 點擊任意的一個箭頭的Action,查看屬性

3.4 Navigation XML 解析

在設計模式下你對導航的設計改變均可以在XML佈局文件中看到,點擊Text按鈕app

你能夠看到XML中的代碼:

<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/home_dest">

    <!-- ...tags for fragments and activities here -->

</navigation>
複製代碼

注意:

  • <navigation> 標籤是整個視圖的跟佈局
  • <navigation> 包括一個或者更多的目標界面,通常爲Activity或者fragment
  • app:startDestination是一個目標界面的特殊屬性,表明着啓動的默認頁面

接下來

<fragment
    android:id="@+id/flow_step_one_dest"
    android:name="com.example.android.codelabs.navigation.FlowStepFragment"
    tools:layout="@layout/flow_step_one_fragment">
    <argument
        .../>

    <action
        android:id="@+id/next_action"
        app:destination="@+id/flow_step_two_dest">
    </action>
</fragment> 
複製代碼

注意

  • android:id是你定義的目標界面的id屬性
  • ndroid:name是你的目標界面的整個包路徑名
  • tools:layout 指定應在圖形編輯器中顯示的佈局

代碼中的<action> <argument>下面會詳細介紹

四、爲導航視圖添加一個目標界面

demo中只有不多的目標接 main,下面咱們能夠新增一個目標界面,首先你須要本身先建立好一個Fragment或者Activity:

每一步的代碼都在demo中能夠找到,你能夠在TODO的地方編寫代碼或與註釋掉的代碼進行比較

  1. 打開res/navigation/mobile_navigation.xml文件,點擊Desgin按鈕
  2. 點擊新建按鈕,選擇settings_fragment

這就是你新建立好的一個目標界面(你也能夠本身在xml中自行添加)

mobile_navigation.xml

<fragment
    android:id="@+id/settings_dest"
    android:name="com.example.android.codelabs.navigation.SettingsFragment"
    android:label="@string/settings"
    tools:layout="@layout/settings_fragment" />
複製代碼

要遵循咱們的命名約定,請將ID從默認設置片斷更改成SettingsFragment

五、使用Navigation Graph導航一個頁面

5.1 界面和導航

Navigation組件遵循導航原則中Navigation指南,指南中建議您使用activities做爲APP的入口,activities包括普通的Navigation例如:BottomNavigation。相比較下,fragment一版做爲一個目標界面。

接下來你須要在佈局中新增NavHostFragment,NavHostFragment經過navGraph與navigation導航編輯器進行關聯

<LinearLayout
    .../>
    <androidx.appcompat.widget.Toolbar
        .../>
    <fragment
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/my_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/mobile_navigation"
        app:defaultNavHost="true"
        />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        .../>
</LinearLayout>
複製代碼

注意

  • 這是一個Activity,它包含了一個普通的Navigation、和一個底部導航以及一個Toobar
  • android:name="androidx.navigation.fragment.NavHostFragment"app:defaultNavHost="true"經過NavHostFragment鏈接系統返回鍵
  • app:navGraph="@navigation/mobile_navigation"經過NavHostFragment鏈接導航的菜單按鈕,導航視圖能夠經過NavHostFragment導航到任意的目標界面

5.2 NavController

最後,當你點擊一個按鈕時,你須要觸發一個導航命令。Navcontroller的觸發navhostfragment中的fragemnt切換。

// Command to navigate to flow_step_one_dest
findNavController().navigate(R.id.flow_step_one_dest)
複製代碼

注意您輸入要導航的目標或操做ID,這些ids是你在xml佈局中定義好的。NavController是很強大的,你能夠調用navigate()或者popBackStack()它能夠將代碼轉化爲匹配的導航操做,這些操做基於您要導航的目標類型。例如:你能夠調用navigate()去跳轉到一個目標界面,NavConroller會調用自身的startActivity()

Kotlin中提供了擴展函數能夠得到與NavHostFragment關聯的NavController對象:

  • Fragment.findNavController()
  • view.findNavController()
  • Activity.findNavController(viewId: Int)

你的NavController和一個NavHostFragment相關聯。所以不管使用哪一種方法,都必須保證fragmengt,view或者view id是NavHostFragmengt自己,或者是它的父類。不然將會拋出異常。

5.3 使用NavController切換頁面

你可使用NavController去切換FlowStepFragment

  1. 打開HomeFragment.kt
  2. onViewCreated() 中find navigate_destination_button
val button = view.findViewById<Button>(R.id.navigate_destination_button)
button?.setOnClickListener {
    findNavController().navigate(R.id.flow_step_one_dest, null)
}
複製代碼
  1. 運行APP點擊Navigate To Destination按鈕,請注意,該按鈕導航到flow_step_one_dest目的地

您也可使用便捷方法Navigation.createNavigateOnClickListener(@IdRes destId: int, bundle: Bundle)。此方法將構建一個OnClickListener導航到給定目標,並使用一組參數傳遞給目標。

val button = view.findViewById<Button>(R.id.navigate_destination_button)
button?.setOnClickListener(
        Navigation.createNavigateOnClickListener(R.id.flow_step_one_dest, null)
)
複製代碼

六、改變過渡動畫

每一個navigate()都有一個默認的過渡動畫

能夠經過包含一組來覆蓋默認轉換以及與該調用關聯的其餘屬性NavOptions。 NavOptions使用一種Builder模式,容許您覆蓋和設置所需的選項。還有一個用於NavOptions的ktx DSL,這是你將要使用的。 對於動畫過渡,您能夠在anim資源文件夾中定義XML動畫資源,而後將這些動畫用於過渡。應用代碼中包含一些示例:

6.1 添加自定義過渡

更新代碼,以便按導航到目標按鈕顯示自定義過渡動畫。

  1. 打開 HomeFragment.kt
  2. 定義NavOptions並將其傳遞給navigate()調用navigate_destination_button
val options = navOptions {
    anim {
        enter = R.anim.slide_in_right
        exit = R.anim.slide_out_left
        popEnter = R.anim.slide_in_left
        popExit = R.anim.slide_out_right
    }
}
view.findViewById<Button>(R.id.navigate_destination_button)?.setOnClickListener {
    findNavController().navigate(R.id.flow_step_one_dest, null, options)
}
複製代碼
  1. 刪除步驟5中添加的代碼(若是它仍然存在)
  2. 確認點擊「 導航到目的地」按鈕會致使片斷滑動到屏幕上,而後按下該片斷會使其滑出屏幕

七、使用操做導航Action

7.1 Actions

導航系統還容許您經過Actions進行導航。如前所述,導航圖中顯示的線條是動做的直觀表示。

按行動導航比目標導航具備如下優點:

  • 您能夠經過應用程序可視化導航路徑
  • 操做能夠包含您能夠設置的其餘關聯屬性,例如轉換動畫,參數值和Backstack行爲
  • 您可使用插件安全args進行導航,您很快就會看到

這是鏈接的操做的可視化和XML,flow_step_one_dest而且flow_step_two_dest

<fragment
    android:id="@+id/flow_step_one_dest"
    android:name="com.example.android.codelabs.navigation.FlowStepFragment">

    <argument
        .../>

    <action
        android:id="@+id/next_action"
        app:destination="@+id/flow_step_two_dest">
    </action>
</fragment>

<fragment
    android:id="@+id/flow_step_two_dest"
    android:name="com.example.android.codelabs.navigation.FlowStepFragment">
    <!-- ...removed for simplicity-->
</fragment>
複製代碼

注意

  • 這些操做嵌套在目標中 - 這是您將從中導航的目標
  • 該操做包括一個引用flow_step_two_dest的目標參數; 這是您要導航到的ID
  • 該操做的ID是「next_action」
  • 這是另外一個鏈接flow_step_two_desthome_dest

<fragment
    android:id="@+id/home_dest"
    android:name="com.example.android.codelabs.navigation.HomeFragment"
    .../>

<fragment
    android:id="@+id/flow_step_two_dest"
    android:name="com.example.android.codelabs.navigation.FlowStepFragment">

    <argument
        .../>

    <action
        android:id="@+id/next_action"
        app:popUpTo="@id/home_dest">
    </action>
</fragment>
複製代碼

注意:

  • 相同的ID next_action用於鏈接做用flow_step_two_desthome_dest。您能夠導航使用next_action ID從任一flow_step_one_destflow_step_two_dest。這是一個示例,說明操做如何提供抽象級別,並能夠根據上下文導航到不一樣的位置。 使用該popUpTo屬性 - 此操做將從後棧中彈出片斷,直到您到達home_dest

7.2 使用Action進行導航

  1. mobile_navigation.xml在設計模式下打開文件
  2. 從拖動箭頭home_destflow_step_one_dest

  1. 選擇操做箭頭(藍色)更改操做的屬性,以便:
  • ID = next_action
  • 轉換爲Enter = slide_in_right
  • Exit = slide_out_left的轉換
  • Pop Enter的轉換= slide_in_left
  • Pop Exit的過渡= slide_out_right

  1. 單擊**「文本」**選項卡 mobile_navigation.xml
<fragment android:id="@+id/home_dest"
        ...>
        
        <action android:id="@+id/next_action"
            app:destination="@+id/flow_step_one"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />
複製代碼
  1. 打開HomeFragment.kt
  2. 添加一個單擊監聽器 navigate_action_button HomeFragment.kt
view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener(
        Navigation.createNavigateOnClickListener(R.id.next_action, null)
)
複製代碼

操做容許您附加NavOptions在導航XML文件中,而不是以編程方式指定它們。

  1. 確認點擊導航到操做如今導航到下一個屏幕。

八、使用安全args進行導航

8.1 安全的Args

導航組件有一個名爲safe args的Gradle插件,它生成簡單的對象和構建器類,以便對爲目標和操做指定的參數進行類型安全訪問。

Safe args容許您在目標之間傳遞值時刪除這樣的代碼:

val username = arguments?.getString("usernameKey")
複製代碼

而是將其替換爲生成setter和getter的代碼。

val username = args.username
複製代碼

因爲其類型安全性,使用安全args生成類的導航是經過操做導航並在導航期間傳遞參數的首選方式。

8.2 使用安全args傳遞值

  1. 打開項目build.gradle文件並注意safe args插件:

build.gradle

dependencies {
        classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
    //...
    }
複製代碼
  1. 打開app/build.gradle文件並注意應用的插件:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'androidx.navigation.safeargs'

android { 
   //...
}
複製代碼
  1. 打開mobile_navigation.xml,並注意如何在flow_step_one_dest目標中定義參數
<fragment
    android:id="@+id/flow_step_one_dest"
    android:name="com.example.android.codelabs.navigation.FlowStepFragment"
    tools:layout="@layout/flow_step_one_fragment">
    <argument
        android:name="flowStepNumber"
        app:argType="integer"
        android:defaultValue="1"/>

    <action...>
    </action>
</fragment>
複製代碼

使用<argument>標記,safeargs生成一個名爲的類FlowStepFragmentArgs

因爲XML包含一個名爲 flowStepNumber,由指定的參數 android:name="flowStepNumber",所以生成的類 FlowStepFragmentArgs將包含一個 flowStepNumber帶有getter和setter 的變量。

  1. 打開 FlowStepFragment.kt
  2. 註釋掉下面顯示的代碼行 FlowStepFragment.kt
/ Comment out this line
// val flowStepNumber = arguments?.getInt("flowStepNumber")
複製代碼

這種舊式代碼不是類型安全的。最好使用安全的args。 6. 更新FlowStepFragment以使用代碼生成的類FlowStepFragmentArgs。這將以FlowStepFragment類型安全的方式獲取參數:

FlowStepFragment.kt

val safeArgs: FlowStepFragmentArgs by navArgs()
val flowStepNumber = safeArgs.flowStepNumber
複製代碼

8.3 安全Args方向類

您還可使用安全args以類型安全的方式導航,不管是否添加參數。您可使用生成的Directions類來完成此操做

經過操做爲每一個不一樣的目標生成方向類。Directions類包含目標具備的每一個操做的方法。

例如,navigate_action_buttonHomeFragment.kt中的單擊偵聽器能夠更改成:

HomeFragment.kt

// Note the usage of curly braces since we are defining the click listener lambda
view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener{
    val flowStepNumberArg = 1
    val action = HomeFragmentDirections.nextAction(flowStepNumberArg)
    findNavController().navigate(action)
}
複製代碼

請注意,在導航圖XML中,您能夠defaultValue爲每一個參數提供一個。若是你沒有,那麼你必須傳遞參數到動做,如圖所示: HomeFragmentDirections.nextAction(flowStepNumberArg)

九、使用菜單,抽屜和底部導航進行導航

9.1 NavigationUI和navigation-ui-ktx

導航組件包括一個NavigationUI類navigation-ui-ktxkotlin擴展。NavigationUI具備將菜單項與導航目的地相關聯的靜態方法,而且navigation-ui-ktx是一組執行相同操做的擴展函數。若是NavigationUI在當前圖形上找到與目標ID相同的菜單項,則會將菜單項配置爲導航到該目標

9.2 將NavigationUI與選項菜單一塊兒使用

使用NavigationUI的最簡單方法之一是簡化選項菜單設置。特別是,NavigationUI簡化了onOptionsItemSelected回調的處理。

  1. 打開MainActivity.kt

請注意,你怎麼已經有代碼膨脹的菜單overflow_menuonCreateOptionsMenu

  1. 打開 res/menu/overflow_menu.xml

  2. 更新溢出菜單以包含 settings_dest

overflow_menu.xml

<item
    android:id="@+id/settings_dest"
    android:icon="@drawable/ic_settings"
    android:menuCategory="secondary"
    android:title="@string/settings" />
複製代碼
  1. 打開 MainActivity.kt

  2. onOptionsItemSelected使用onNavDestinationSelected輔助方法處理NavigationUI句柄。若是菜單項不是要導航,請使用super.onOptionsItemSelected

MainActivity.kt

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return item.onNavDestinationSelected(findNavController(R.id.my_nav_host_fragment))
            || super.onOptionsItemSelected(item)
}
複製代碼
  1. 運行您的應用程序。您應該有一個功能的ActionBar菜單導航到SettingsFragment。

9.3 使用NavigationUI配置底部導航

代碼已經包含用於實現底部導航的XML佈局代碼,這就是您看到底部導航欄的緣由。但它不會導航到任何地方。

  1. 打開res/layout/navigation_activity/navigation_activity.xml (h470dp)並單擊「 文本」選項卡

請注意底部導航的XML佈局代碼是如何引用的 bottom_nav_menu.xml

navigation_activity.xml(h470dp)

com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_nav_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:menu="@menu/bottom_nav_menu" />
複製代碼
  1. 打開 ````res/menu/bottom_nav_menu.xml``` 請注意底部導航有兩個項目,它們的ID與導航圖形目標的目標相匹配

bottom_nav_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@id/home_dest"
        android:icon="@drawable/ic_home"
        android:title="@string/home" />
    <item
        android:id="@id/deeplink_dest"
        android:icon="@drawable/ic_android"
        android:title="@string/deeplink" />
</menu>
複製代碼

讓底部導航實際上使用NavigationUI作一些事情。

  1. 打開 MainActivity.kt

  2. setupBottomNavMenu使用實現方法setupWithNavController(bottomNavigationView: BottomNavigationView, navController: NavController)

MainActivity.kt

private fun setupBottomNavMenu(navController: NavController) {
    val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav_view)
    bottomNav?.setupWithNavController(navController)
}

複製代碼

9.4 使用NavigationUI配置導航抽屜

最後,讓咱們使用NavigationUI配置側面導航和導航抽屜,包括處理ActionBar和正確的導航。若是您有足夠大的屏幕或者屏幕過短而沒法進行底部導航,您會看到這一點。

首先觀察應用程序中已有適當的佈局XML代碼。

  1. 打開navigation_activity.xml和navigation_activity.xml (w960dp)

請注意兩個佈局如何包含鏈接到nav_drawer_menu 的NavigationView。在平板電腦版本(w960dp)中,NavigationView始終在屏幕上。在較小的設備上,NavigationView 嵌套在DrawerLayout中。

如今開始實施NavigationView導航。

  1. 打開 MainActivity.kt

  2. setupNavigationMenu使用實現方法setupWithNavController(navigationView: NavigationView, navController: NavController)。請注意該方法的版本如何使用NavigationView而不是a BottomNavigationView。

MainActivity.kt

private fun setupNavigationMenu(navController: NavController) {
    val sideNavView = findViewById<NavigationView>(R.id.nav_view)
    sideNavView?.setupWithNavController(navController)
}
複製代碼

如今導航視圖菜單將顯示在屏幕上,但不會影響ActionBar。

設置ActionBar須要建立一個實例AppBarConfiguration。目的AppBarConfiguration是爲工具欄,摺疊工具欄和操做欄指定所需的配置選項。配置選項包括欄是否必須處理抽屜佈局以及哪些目的地被視爲頂級目的地。

頂級目標是應用程序的根級目標。這些目的地不會在應用欄中顯示「向上」按鈕,若是目的地使用抽屜佈局,它們會顯示抽屜圖標。

  1. AppBarConfiguration經過傳遞一組頂級目標ID和抽屜佈局來建立。

MainActivity.kt

val drawerLayout : DrawerLayout? = findViewById(R.id.drawer_layout)
appBarConfiguration = AppBarConfiguration(
        setOf(R.id.home_dest, R.id.deeplink_dest),
        drawerLayout)
複製代碼

如何肯定頂級目的地 經過全局導航UI可到達的目的地,例如底部導航或側面導航,全部目標都顯示給用戶,由於它們位於層次結構的同一頂層。所以,它們是頂級目的地。home_dest而且deeplink_dest在底部導航中,咱們但願抽屜圖標顯示在這兩個目的地上,所以它們是頂級目的地。 請注意,起始目標始終被視爲頂級目標。若是未指定頂級目標列表,則惟一的頂級目標是您的起始目標。您能夠AppBarConfiguration在文檔中瞭解更多信息。

5.實施 setupActionBarWithNavController

MainActivity.kt

private fun setupActionBar(navController: NavController,
                           appBarConfig : AppBarConfiguration) {
    setupActionBarWithNavController(navController, appBarConfig)
}
複製代碼

您還應該讓NavigationUI處理按下向上按鈕時發生的狀況。

  1. 覆蓋onSupportNavigationUpNavigationUI.navigateUp使用相同的呼叫AppBarConfiguration

MainActivity.kt

override fun onSupportNavigateUp(): Boolean {
    return findNavController(R.id.my_nav_host_fragment).navigateUp(appBarConfiguration)
}
複製代碼
  1. 運行您的代碼。若是您在拆分屏幕中打開應用程序,則應該有一個可用的導航抽屜。向上圖標和抽屜圖標應在適當的時間顯示並正常工做。

佈局navigation_activity.xml(h470dp)將在縱向模式下在手機上使用。這種佈局也未包含該導航抽屜,而是包括底部導航,這就是爲何你要在分屏打開應用程序,看看抽屜式導航欄。沒有導航抽屜和底部導航佈局的緣由是由於Material Design準則警告不要這樣作。

添加新目的地NavigationView很容易。導航抽屜使用向上和向後導航後,只需添加新菜單項便可。

  1. 打開menu/nav_drawer_menu.xml

9.添加新菜單項 settings_dest

nav_drawer_menu.xml

<item
    android:id="@+id/settings_dest"
    android:icon="@drawable/ic_settings"
    android:title="@string/settings" />
複製代碼

十、深度連接到目的地

10.1 深層連接和導航

導航組件還包括深層連接支持。深層連接是一種跳入應用導航中間的方式,不管是來自實際的URL連接仍是來自通知的待處理意圖。

使用導航庫處理深層連接的一個好處是,它能夠確保用戶使用來自其餘入口點(如應用程序小部件,通知或Web連接)的相應後備堆啓動正確的目標(在下一步中介紹)。

導航提供了一個NavDeepLinkBuilder類來構建一個PendingIntent將用戶帶到特定目的地的類

10.2 添加深層連接

咱們將使用將NavDeepLinkBuilderapp小部件鏈接到目標。

1.打開 DeepLinkAppWidgetProvider.kt

2.添加一個PendingIntent構造NavDeepLinkBuilder

DeepLinkAppWidgetProvider

val args = Bundle()
args.putString("myarg", "From Widget");
val pendingIntent = NavDeepLinkBuilder(context)
        .setGraph(R.navigation.mobile_navigation)
        .setDestination(R.id.deeplink_dest)
        .setArguments(args)
        .createPendingIntent()

remoteViews.setOnClickPendingIntent(R.id.deep_link_button, pendingIntent)
複製代碼

注意:

  • setGraph 包括導航圖。
  • setDestination 指定連接的位置。
  • setArguments 包括您要傳遞到深層連接的任何參數。

默認狀況下NavDeepLinkBuilder將啓動您的啓動器活動。您能夠經過將活動做爲上下文傳遞或經過設置顯式活動類來覆蓋此行爲setComponentName()

  1. 將Deep Link小部件添加到主屏幕。點擊並按住主屏幕以查看添加小部件的選項

完成後,您將擁有一個深層連接小部件。

4. 點擊窗口小部件,並驗證Android目標是否以正確的參數打開。它應該在頂部說「From Widget」,由於那是你在DeepLinkAppWidgetProvider中傳遞的參數

  1. 確認按下後退按鈕將您帶到home_dest目的地。

爲方便起見,你也能夠調用NavController的createDeepLink()方法使用Context從當前和導航圖NavController。

10.3 DeepLink Backstack

使用您傳入的導航圖肯定深層連接的後臺堆棧。若是您選擇的顯式活動具備父活動,則還包括這些父活動。

使用指定的目標生成backstack app:startDestination。在這個應用程序中,咱們只有一個活動和一個級別的導航,所以backstack將帶您到home_dest目的地。

更復雜的導航能夠包括嵌套導航圖。的app:startDestination在嵌套圖的每一個水平決定返回堆棧。有關深層連接和嵌套圖形的更多信息,請查看導航原理

十一、 將Web連接與目標關聯

11.1 元素

深層連接最多見的用途之一是容許Web連接在您的應用中打開活動。傳統上,您將使用intent-filter並將URL與您要打開的活動相關聯。

導航庫使這很是簡單,並容許您將URL直接映射到導航圖中的目標。

是您能夠添加到圖表中目標的元素。每一個元素都有一個必需的屬性:app:uri。

除了直接URI匹配外,還支持如下功能:

  • 沒有方案的URI被假定爲http和https。例如,www.example.com將匹配http://www.example.com和https://www.example.com。
  • 您可使用形式{placeholder_name}匹配一個或多個字符的佔位符。佔位符的String值在參數Bundle中可用,該參數具- 有相同名稱的鍵。例如,www.example.com/users/{id}將…
  • 您可使用.*通配符匹配零個或多個字符。
  • NavController將自動處理ACTION_VIEW意圖並尋找匹配的深層連接

11.2 使用添加基於URI的深層連接

在此步驟中,您將添加指向www.example.com的深層連接。

  1. 打開 mobile_navigation.xml

  2. 將元素添加到deeplink_dest目標。

mobile_navigation.xml

<fragment
    android:id="@+id/deeplink_dest"
    android:name="com.example.android.codelabs.navigation.DeepLinkFragment"
    android:label="@string/deeplink"
    tools:layout="@layout/deeplink_fragment">

    <argument
        android:name="myarg"
        android:defaultValue="Android!"/>

    <deepLink app:uri="www.example.com/{myarg}" />
</fragment>
複製代碼
  1. 打開 AndroidManifest.xml

  2. 添加nav-graph標籤。這將確保生成適當的intent過濾器

AndroidManifest.xml中

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <nav-graph android:value="@navigation/mobile_navigation" />
</activity>
複製代碼

若是您想知道生成了什麼,能夠在輸出APK中找到結果。 在項目視圖中,導航到app - > build - > outputs - > apk - > debug - > app-debug.apk 雙擊app-debug.apk以在APK Analyzer中打開。在這裏,您將可以看到生成的AndroidManifest。

  1. 使用深層連接啓動您的應用。有兩種方法能夠作到這一點:
  • 用途adb

adb shell am start -a android.intent.action.VIEW -d「http://www.example.com/urlTest」

  • 經過Google應用導航。您應該可以將www.example.com/urlTest放在搜索欄中,並顯示消歧窗口。選擇導航codelab

相關文章
相關標籤/搜索