Google官方的描述:
今天,我们宣布推出Navigation组件,作为构建您的应用内界面的框架,重点是让单 Activity 应用成为首选架构。利用Navigation组件对 Fragment 的原生支持,您可以获得架构组件的所有好处(例如生命周期和 ViewModel),同时让此组件为您处理 FragmentTransaction 的复杂性。此外,Navigation组件还可以让您声明我们为您处理的转场。它可以自动构建正确的“向上”和“返回”行为,包含对深层链接的完整支持,并提供了帮助程序,用于将导航关联到合适的 UI 小部件,例如抽屉式导航栏和底部导航。
添加依赖
1 2
| implementation "android.arch.navigation:navigation-fragment:1.0.0" implementation "android.arch.navigation:navigation-ui:1.0.0"
|
添加fragment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| class NavigationFragment1 extends Fragment{
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_navigation,container,false); ((TextView)rootView.findViewById(R.id.tv_navi)).setText("NavigationFragment1"); rootView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Navigation.findNavController(v).navigate(R.id.nav_page2); } }); return rootView; } }
class NavigationFragment2 extends Fragment{
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_navigation,container,false); ((TextView)rootView.findViewById(R.id.tv_navi)).setText("NavigationFragment2"); rootView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Navigation.findNavController(v).navigate(R.id.nav_page3); } }); return rootView; } }
class NavigationFragment3 extends Fragment{
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_navigation,container,false); ((TextView)rootView.findViewById(R.id.tv_navi)).setText("NavigationFragment3"); rootView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Navigation.findNavController(v).navigateUp(); } }); return rootView; } }
|
新建导航文件
在res目录下新建navigation文件夹,然后新建一个navigation的resource文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?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" android:id="@+id/nav" app:startDestination="@id/nav1"> <fragment android:id="@+id/nav1" android:name="com.example.jetpackdemo.navigation.NavigationFragment1"> <action android:id="@+id/nav_page2" app:destination="@id/nav2"></action> </fragment>
<fragment android:id="@+id/nav2" android:name="com.example.jetpackdemo.navigation.NavigationFragment2" > <action android:id="@+id/nav_page3" app:destination="@id/nav3"></action> <action android:id="@+id/nav_page1" app:popUpTo="@id/nav1"></action> </fragment>
<fragment android:id="@+id/nav3" android:name="com.example.jetpackdemo.navigation.NavigationFragment3"> <action android:id="@+id/nav_page_1" app:destination="@id/nav1"></action> </fragment>
</navigation>
|
编辑MainActivity
在MainActivity的xml中添加NavHostFragment:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto">
<fragment android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/nav_fragment" android:name="androidx.navigation.fragment.NavHostFragment" app:defaultNavHost="true" app:navGraph="@navigation/nav" />
</FrameLayout>
|
这个相当于是导航界面的容器,里面添加了一个NavHostFragment。同时在activity中重写onSupportNavigateUp方法,将back键点击事件的委托出去。
Navigation.findNavController(View) 返回了一个 NavController ,它是整个 Navigation 架构中 最重要的核心类,我们所有的导航行为都由 NavController 处理。里面有两个方法navigate和navigateUp,表示跳转到指定的fragment和上一个fragment。
NavGraphFragment
NavGraphFragment内部实例化了一个FrameLayout, 作为ViewGroup的载体,导航并展示其它Fragment。
在xml配置的app:defaultNavHost="true"这个属性意味着你的NavGraphFragment将会 拦截系统Back键的点击事件,同时 必须重写 Activity的 onSupportNavigateUp() 方法。
nav.xml
nav.xml以声明其导航的结构。
在跟节点中配置papp:startDestination="@id/nav1",表示nav1 的fragment会被默认加载到容器中。
在每个fragment‘中会声明action,其中的app:destination的属性,声明了这个行为导航的 destination(目的地),我们可以看到,它会指印跳转到 对应id 的Fragment。
同时Navigation还提供了一个 app:popUpTo 属性,它的作用是声明导航行为 将 返回到 id对应的Fragment