Android 中 navigation 的使用
一、简介
Google 在2018年推出了 Android Jetpack,在Jetpack里有一种管理 fragment 的新模式 navigation。
Navigation 除了可以做 APP 引导页面以外,也可以使用在 APP 主页的导航。又比如一个 APP 中各个功能模块都使用了 activity 中相同的部分,则可以将 Activity 提取出一个模板,内容部分都使用 fragment 来替换。因此 navigation 就成了管理 fragment 重要的架构。
要注意的是它不单单能管理 Fragment,也可以管理 Activity。
二、使用
1、选中项目资源文件夹 res 右击 >> New >> New Resource Directory
2、选中 navigation 点击创建
3、选中项目资源文件夹 res 右击 >> New >> New Resource File
4、选择 navigation ,输入xml文件名称,点击ok创建
5、打开这个文件选择,模式使用视图手动配置
三、navigation 的属性
1.android:id="@+id/demo_nav" 这个属性是你这个xml文件navigation的id,很重要,我们需要在activity的xml布局里引用,记得写上不要忘记
2.app:startDestination="@id/one" 这个属性是你首次加载的第一个页面,很重要,一般就是第一个fragment
fragment 里的属性:其实就是一个节点你也可以理解成一个fragment
1.android:id="@+id/one" 每一个fragment节点都需要有自己的id,很重要. 我们需要在后面的节点上使用这些id指定跳转目标
2.android:name="demo.yt.com.demo.fragment.BlankFragment" 这个属性是你这个节点所对应的fragment(需要你导入指定的fragment文件路径),这个很重要
3.android:label="BlankFragment" 一个标签名称,用于记录这个节点的标签信息(大概可能是在代码里的Intent里获取来知晓此次是那个fragment节点在跳转,没深究了)
4.tools:layout="@layout/fragment_blank" 这个属性不是重要的,设置它后你可以在切换到Design模式后看到,视图页面的fragment的预览图(就在上面的图片里,可以直接看到fragment效果)
action 里的属性:action 负责编写跳转动作
1. android:id="@+id/action_one_to_two" 这个很重要,它是这个跳转动作的id, 这个id我们将在后面的代码中调用,用于执行fragment的跳转
2. app:destination="@id/two" 跳转的目标fragment,这个很重要
<?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/demo_nav"
app:startDestination="@id/one">
<fragment android:id="@+id/one"
android:name="demo.yt.com.demo.fragment.BlankFragment"
android:label="BlankFragment"
tools:layout="@layout/fragment_blank">
<action
android:id="@+id/action_one_to_two"
app:destination="@id/two" />
</fragment>
<fragment android:id="@+id/two"
android:name="demo.yt.com.demo.fragment.Blank2Fragment"
android:label="BlankFragment"
tools:layout="@layout/fragment_blank2">
<action
android:id="@+id/action_two_to_three"
app:destination="@id/three" />
</fragment>
<fragment android:id="@+id/three"
android:name="demo.yt.com.demo.fragment.Blank3Fragment"
android:label="BlankFragment"
tools:layout="@layout/fragment_blank3"/>
</navigation>
四、navigation 与 Activity 关联
现在我们已经创建了navigation,但是使用它还需要一个根Activity,它毕竟还是需要依托Activity的.
1.创建了一个叫DemoActivity的Activity.
android:name="androidx.navigation.fragment.NavHostFragment" 这个非常重要,这是你告知fragment需要使用navigation模式的关键属性,另外它是固定死的.你必需写.
app:defaultNavHost="true" 这是你实现物理按键(比如返回键),是按一下退出一个fragment 还是直接退出这个Activity的关键属性
app:navGraph="@navigation/demo_nav" 很重要,这就是我们前面创建的 navigation 的xml文件
<?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=".fragment.DemoActivity">
<fragment
android:id="@+id/demo_fragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/demo_nav"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
2、实现fragment跳转与返回
进入到DemoActivity后,首先会自动加载到第一个fragment. 然后我们看看如何跳转到其他fragment中
从第一个碎片跳转到第二个碎片,关键代码 Navigation.findNavController(getView()).navigate(R.id.action_one_to_two);
public class BlankFragment extends Fragment {
private Button mBtnInputFragment2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_blank, container, false);;
mBtnInputFragment2 = view.findViewById(R.id.btn_input_fragment2);
mBtnInputFragment2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Navigation.findNavController(getView()).navigate(R.id.action_one_to_two);//这个id就是navigation里的action的id
}
});
return view;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onDetach() {
super.onDetach();
}
}
从第二个碎片返回到第一个碎片,关键代码 Navigation.findNavController(getView()).popBackStack();
public class Blank2Fragment extends Fragment {
private Button mBtnInputFragment3, mBtnBack;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank2, container, false);
mBtnInputFragment3 = view.findViewById(R.id.btn_input_fragment3);
mBtnBack = view.findViewById(R.id.back);
mBtnInputFragment3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Navigation.findNavController(getView()).navigate(R.id.action_two_to_three); //进入第三个碎片
}
});
mBtnBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Navigation.findNavController(getView()).popBackStack(); //返回上一个碎片
}
});
return view;
}
}