谷歌在jetpack推出了navigation框架用来管理页面的跳转。地址
安装
首先Studio要支持3.2版本,然后要让工具支持Navigation编辑。 File > Settings对话框中选择Experimental,勾选Enable Navigation Edito,接着重启。最后添加依赖
implementation "android.arch.navigation:navigation-fragment:1.0.0-alpha07" // use -ktx for Kotlin
implementation "android.arch.navigation:navigation-ui:1.0.0-alpha07" // use -ktx for Kotlin
这个时候就可以在res目录下新建Android resource File。 从Resource type的下拉列表中选择navigation类型。studio会在res下创建navigation目录,并创建navigation_graph.xml。
Activity需要添加NavHost到layout中来支持导航。NavHost是一个接口,是一个空视图。
public interface NavHost {
/**
* Returns the {@link NavController navigation controller} for this navigation host.
*
* @return this host's navigation controller
*/
@NonNull
NavController getNavController();
}
它的默认实现是NavHostFragment。包含NavHost后,必须使用navGraph属性将导航图与NavHostFragment相关联。 以下代码段显示了如何在活动的布局文件中包含NavHostFragment并将导航图与NavHostFragment相关联:
<?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 finalHost = NavHostFragment.create(R.navigation.nav_graph);
getSupportFragmentManager().beginTransaction(
.replace(R.id.my_nav_host_fragment, finalHost)
.setPrimaryNavigationFragment(finalHost) // this is the equivalent to app:defaultNavHost="true"
.commit();
注意标签不再是fragment,而是FrameLayout
-------------------------------------------
<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">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/my_nav_host_fragment"
app:defaultNavHost="true"
/>
</android.support.constraint.ConstraintLayout>
UI目的地
nav_graph:
<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/title_screen">
<fragment
android:name="com.example.administrator.navigationdemo.TitleScreen"
android:id="@+id/title_screen">
<action
android:id="@+id/action_title_screen_to_register"
app:destination="@id/register"/>
</fragment>
<fragment
android:name="com.example.administrator.navigationdemo.Register"
android:id="@+id/register"/>
</navigation>
导航 首先要有初始地app:startDestination="@id/title_screen"
导航到目的地是通过类NavController,可以通过三个静态方法得到
1. NavHostFragment.findNavController(Fragment)
2. Navigation.findNavController(Activity, @IdRes int viewId)
3. Navigation.findNavController(View)
然后调用navigate()
,该方法即接收fragmentId(如R.id.register
)或者actionId(如R.id.action_title_screen_to_register
)。而actionId更多的可以通过transition框架实现页面跳转的动画效果。navigate还接受bundle参数用可以来传递数据。