Navigation導航編輯器旨在簡化Android開發中導航的實現,能夠幫助咱們很好的處理Activity和fragment之間經過FragmentTransaction交互的複雜性,也能夠很好的處理頁面的轉場效果;Deeplink的支持,繞過activity直接跳到fragment;而且傳遞參數更安全。在Android Studio3.2能夠使用。android
implementation "android.arch.navigation:navigation-fragment:1.0.0-rc01" // use -ktx for Kotlin implementation "android.arch.navigation:navigation-ui:1.0.0-rc01"
class IndexFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.index_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) var args = arguments?.let { IndexFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle txt_desc.text = "${args!!.topBarTitle}頁面" } }
class BallFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.ball_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) var args = arguments?.let { BallFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle txt_desc.text = "${args!!.topBarTitle}頁面" } }
<?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" android:id="@+id/nav_graph" app:startDestination="@id/indexFragment"> <!-- app:startDestination是起始Destination,必須指定 --> <fragment android:id="@+id/indexFragment" android:name="com.fomin.demo.bar.IndexFragment" android:label="IndexFragment" tools:layout="@layout/index_fragment"> <!--參數傳遞--> <argument android:name="topBarTitle" app:argType="string" android:defaultValue="主頁"/> <!--跳轉動做--> <action android:id="@+id/action_indexFragment_to_ballFragment" app:destination="@id/ballFragment"/> </fragment> <fragment android:id="@+id/ballFragment" android:name="com.fomin.demo.bar.BallFragment" android:label="BallFragment" tools:layout="@layout/ball_fragment"> <argument android:name="topBarTitle" app:argType="string" android:defaultValue="足球"/> </fragment> </navigation>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/nav_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph"/> </LinearLayout>
在Activity中添加以下代碼安全
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) } override fun onSupportNavigateUp(): Boolean { return Navigation.findNavController(this, R.id.nav_fragment).navigateUp() } }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) var args = arguments?.let { IndexFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle btn_goto_ball.setOnClickListener { Navigation.findNavController(it).navigate(R.id.action_indexFragment_to_ballFragment) }//點擊跳轉時間 }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) var args = arguments?.let { BallFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle top_bar_back.visibility = if (args!!.showBack == 1) View.VISIBLE else View.GONE txt_desc.text = "${args!!.topBarTitle}頁面" top_bar_back.setOnClickListener { Navigation.findNavController(it).popBackStack() }//回退事件 }
好了,Navigation入門講解完了,上面代碼對於Fragment 並不是是經過原生的 FragmentManager 和 FragmentTransaction 進行控制的,而是經過如下Navigation.findNavController(params)進行的控制。接下來會對Navigation詳細講解。app
此屬性位於navigation 根節點上,是導航器默認加載在Activity的視圖,是必須設置的。編輯器
<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" android:id="@+id/nav_graph" app:startDestination="@id/indexFragment"> <fragment android:id="@+id/ballFragment" android:name="com.fomin.demo.bar.BallFragment" android:label="BallFragment" tools:layout="@layout/ball_fragment"/> </navigation>
navigation能夠添加fragment和activity的視圖,須要關注的屬性android:id和android:name,name是所在Fragmet/Activity類所在包名,id就不解釋了,衆所周知。ide
使用參數傳遞,須要module的build.gradle添加:apply plugin: 'androidx.navigation.safeargs'佈局
<fragment android:id="@+id/ballFragment" android:name="com.fomin.demo.bar.BallFragment" android:label="BallFragment" tools:layout="@layout/ball_fragment"> <argument android:name="topBarTitle" app:argType="string" android:defaultValue="足球"/> </fragment>
視圖之間的參數傳遞屬性,argType能夠支持string、integer、reference,long,float,boolean和Parcelable對象等。增長屬性以後須要Rebuild一下,IDE會生成相關視圖的Args類。如:gradle
public class BallFragmentArgs implements NavArgs { 省略.... @NonNull public String getTopBarTitle() { return (String) arguments.get("topBarTitle"); } 省略.... }
參數傳遞動畫
btn_goto_ball.setOnClickListener { val bundle = Bundle() bundle.putString("topBarTitle", "籃球") Navigation.findNavController(it).navigate(R.id.action_indexFragment_to_ballFragment, bundle) }
獲取傳遞參數值ui
var args = arguments?.let { BallFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle
動做,即跳轉動做,從視圖A跳轉到視圖B的動做this
<fragment android:id="@+id/indexFragment" android:name="com.fomin.demo.bar.IndexFragment" android:label="IndexFragment" tools:layout="@layout/index_fragment"> <!--跳轉動做--> <action android:id="@+id/action_indexFragment_to_ballFragment" app:destination="@id/ballFragment"/> </fragment>
app:destination的屬性,聲明瞭這個行爲導航的目的地id爲ballFragment的視圖
android:id 這個id做爲Action惟一的 標識,在視圖類的某個點擊事件中,咱們經過id指向對應的行爲
btn_goto_ball.setOnClickListener { Navigation.findNavController(it).navigate(R.id.action_indexFragment_to_ballFragment) }
日常頁面跳轉都會使用到相關的轉場動畫,action也爲轉場動畫提供了enterAnim、exitAnim、popEnterAnim、popExitAnim四個動畫屬性,能夠設置相關的anim動畫資源。
此外,還提供了一個app:popUpTo屬性,它的做用是聲明導航行爲將返回到id對應的Fragment。
使用deep-link能夠建立深層連接,相似activity的自定義URL使用Scheme方式來跳轉,能夠直接跳轉到指定fragment/activity
<fragment android:id="@+id/ballFragment" android:name="com.fomin.demo.bar.BallFragment" android:label="BallFragment" tools:layout="@layout/ball_fragment"> <deepLink app:uri="http://www.fomin.com/login"/> </fragment>
在Manifest.xml添加規則
<activity android:name=".login.LoginActivity"> <nav-graph android:value="@navigation/nav_graph2"/> </activity>
NavHostFragment在佈局中提供了一個區域,用於進行Navigation。
<fragment android:id="@+id/nav_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph2"/>
android:name指定NavHostFragment包名,必填項;app:navGraph指定navigation的資源文件;app:defaultNavHost="true"可確保NavHostFragment攔截系統「後退」按鈕。 也能夠在代碼上設置,如:
override fun onSupportNavigateUp(): Boolean { return Navigation.findNavController(this, R.id.nav_fragment).navigateUp() }
navigation提供了Navigation和NavController的類;Navigation此類提供了用於從應用程序中的各個常見位置查找相關NavController實例的實用程序,或用於執行導航以響應UI事件的實用程序;而NavController管理NavHost中的應用程序導航。