看完Demo,写个例子练手吧。
基础配置就不提了,和官方文档上提及的一样。
首先设计跳转结构。
总共七个碎片,A-G。具体逻辑图上可看出,分别包含了碎片跳碎片,碎片跳activity,两个碎片跳转到相同碎片等类型动作。
主界面如图。图中显示的是A Fragment的布局。
首先我们看看Activity内的配置。
NavHostFragment host = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_nav_test);
NavController navController = host.getNavController();
navController.addOnNavigatedListener(new NavController.OnNavigatedListener() {
@Override
public void onNavigated(@NonNull NavController controller, @NonNull NavDestination destination) {
String dest = getResources().getResourceName(destination.getId());
Toast.makeText(NavigationDemoTestActivity.this , "Navigated to " + dest , Toast.LENGTH_SHORT ).show();
}
});
activity布局:
fragment>
navigation资源直接在布局中被Fragment持有。而Activity中拿到fragment的目的主要是拿到controller,从而获得navigation的监听。
下一步进入navigation资源中一看究竟:
<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"
app:startDestination="@+id/nav_test_a_fragment">
通过配置startDestination的ID指定起始fragment,有些类似给activity配置清单文件了,我觉得照这样来理解会更容易一些。
<fragment
android:id="@+id/nav_test_a_fragment"
android:name="com.test.media.marcy.mediatestdemo.navigationDemo.ui.fragment.NavTestAFragment"
android:label="activity_navigation_demo_test"
tools:layout="@layout/fragment_demo_test_main" >
<action
android:id="@+id/action_b"
app:destination="@id/nav_test_b_fragment">action>
<action
android:id="@+id/action_e"
app:destination="@id/nav_test_e_fragment">action>
<action
android:id="@+id/action_f"
app:destination="@id/nav_test_f_fragment">action>
<action
android:id="@+id/action_g"
app:destination="@id/nav_test_g_fragment">action>
fragment>
绑定了四个action,属于navigation跳转的一种方式。接着进fragment再进行配置.
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle bundle = new Bundle();
bundle.putString("key" , getClass().getName() + "->" + "\n" );
mBinding.btJumpToB.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_b , bundle));
mBinding.btJumpToE.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_e , bundle));
mBinding.btJumpToF.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_f , bundle));
view.findViewById(R.id.bt_jump_to_G).setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_g , bundle));
}
因为用着MVVM框架所以控件都用binding引用了。如果用的不是mvvm直接findviewbyid就行了,和跳转到G一样。
此处传递了一个bundle用于后一个fragment接收。
下一步看跳转的BFragment相关代码:
viewModel.setmTvContent(getArguments().getString("key"));
view.findViewById(R.id.bt_jump).setOnClickListener(Navigation.createNavigateOnClickListener(R.id.nav_test_c_fragment , bundle));
mBinding.btBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().popBackStack();
}
});
获取传递的数据使用了getArguments,和getIntent异曲同工。
此处跳转响应使用了另一种方法,也即是不使用actionid,而是直接调用了navigation里配置的FragmentId进行跳转。
navigation想和activity一样finish掉activity的方式来结束fragment的话使用出栈就可以,也就是
getActivity().getSupportFragmentManager().popBackStack();
毕竟整套框架控制fragment的模式应该就是让碎片依次入栈管理。
从碎片跳到下一个activity按照正常方式走就行
mBinding.btJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getActivity() , MainActivity.class));
}
});