【Navigation】
“一个APP只需要一个Activity”,少用Activity多用Fragment
用来管理Fragment的切换,并且可以通过可视化的方式,看见App的交互流程。这完美的契合了Jake Wharton大神单Activity的建议。所以说它并不是用来代替 startActivity,而是用来代替 FragmentTransaction 的相关操作。
名词 | 释义 |
Navigation Graph | Navigation资源文件,用户切换到可视化界面可以查看各个界面跳转路线 |
NavHostFragment | 当前Fragment的容器 |
NavController | 导航的控制者 |
【添加依赖】
def nav_version = "2.3.3"
implementation "android.arch.navigation:navigation-fragment:$nav_version"
implementation "android.arch.navigation:navigation-ui:$nav_version"
【创建Navigation文件】
(打开 Settings -> Experimental -> Enable Navigation Editor,没有该选项就无视)
在 res 目录右击,选择 New > Android Resource Directory,Resource type 选择 navigation。再在 navigation 文件夹上右键,选择 New > Navigation Resource File。
节点 | 标签 | 说明 |
<navigation> | app:startDestination | 通过 @id 设置默认显示的 Fragment |
<activity / fragment> | android:name | 指定的 Activity/Fragment 文件的包名路径 |
android:label | 别名 | |
tools:layout | 指定的 Activity/Fragment 的布局文件 | |
<action> | android:id | 代码跳转时要用到这个 ID |
app:destination | 要跳转到的目标 fragment ID |
【Activity.xml中】
android:name | 固定写法,声明这是一个 NavHostFragment |
app:navGraph | 指定 Navigation 资源文件 |
app:defaultNavHost | 让 Navigation 处理返回事件,而不是 finish 掉 Activity |
<FragmentContainerView
android:id="@+id/navHost"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav" />
【处理跳转】
通过 NavController 对象的 navigate()方法跳转,通过bundle传参。如果跳转到 Activity,可以从 intent.extras 获取到 bundle,如果是 Fragment,则从 getArguments() 获取到。
NavController 三种获取方法 | NavHostFragment.findNavController(Fragment) | 在Fragment中使用 |
Navigation.findNavController(Activity activity, int viewId) | 在Activity中使用,id指向NavHostFragment | |
Navigation.findNavController(View view) | 在Activity中使用,view是findViewById出来的NavHostFragment |
Bundle bundle = new Bundle()
bundle.putString("name", "SouthernBox")
NavHostFragment.findNavController(this).navigate(R.id.action_firstFragment_to_secondFragment, bundle)
【返回控制】
navigateUp() | 只能一级一级返回,底层使用的下面这个 |
popBackStack() | 可以指定跳转 |
【跳转并传递参数】
AFragment() {
Bundle args = new Bundle();
args.putString("userName", "张三");
Navigation.findNavController(getView()).navigate(R.id.action_AFragment_to_BFragment, args);
}
BFragment{
String ueserName = getArguments().getString("userName");
}