Navigation是什么
导航,用户导航、进入和退出应用不同内容片段交互。按钮点击、应用栏、抽屉式导航栏等模式。
- 导航图:导航相关xml资源,单个内容区域(目标)获取可能路径。
- NavHost:目标的空白容器。默认NavHost实现(NavHostFragment),显示Fragment目标。
- NavController:在NavHost管理应用的导航对象。NavController控制NavHost目标内容。
优势:
- 处理Fragment事物
- 正确处理往返操作
- 动画和转换提供标准化资源
- 实现和处理深层链接
- 导航界面模式,用户极少额外工作
- Safe Args 目标之间导航和传递数据提供安全的Gradle插件
- ViewModel支持,限定导航视图,共享与界面相关数据
- Navigation Editor来查看编辑导航视图
简单使用
build.gradle引入:
dependencies {
···
implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.navigation:navigation-ui:2.3.0'
}
建立导航图
![](https://img.haomeiwen.com/i7522223/a918cb35712a7a65.png)
name:导航文件名,type: Navigation
![](https://img.haomeiwen.com/i7522223/566ff1dfea3eca20.png)
完成后,res/navigation/nav_graph.xml
![](https://img.haomeiwen.com/i7522223/a2e150f182445ee3.png)
可以点击上方+号图标添加,也可手动写xml
startDestination指定mainFragment,对应fragment_main.xml布局
Navigation默认Fragment,需要在Activity(主NavigationActivity)布局中指定
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".navigation.NavigationActivity">
<fragment
android:id="@+id/nav_host_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"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
defaultNavHost=true,这个fragment默认NavHost,每个导航图只能指定默认NavHost。name配置androidx.navigation.fragment.NavHostFragment;navGraph配置nav_graph即指定nav_graph为导航视图。当activity启动,会通过activity布局fragment去加载导航视图中的startDestination配置fragment。
导航
通过Fragment导航另一个Fragment
public class MainFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main,container,false);
view.findViewById(R.id.tvLogin).setOnClickListener(v->{
Bundle bundle = new Bundle();
bundle.putString("name","login");
Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_loginFragment,bundle);
});
return view;
}
}
点击按钮,通过Navigation.findNavController(v).navigate()导航,Bundle进行传值。
目标Fragment,通过getArguments()来获取数据
public class LoginFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
String name = getArguments().getString("name",null);
Toast.makeText(getContext(),name,Toast.LENGTH_LONG).show();
View view = inflater.inflate(R.layout.fragment_login,container,false);
view.findViewById(R.id.tvBack).setOnClickListener(v->{
Navigation.findNavController(v).popBackStack();
});
return view;
}
}
通过Navigation.findNavController(v).popBackStack()返回上一个Fragment。
原理
activity启动时,实例化NavHostFragment,解析导航哪个视图,获取graphid,是否默认Host:defaultHost,然后onAttach方法。
如果想导航其他Fragment,用Navigation.findNavController(v).navigate(resId)。
网友评论