一个巧妙的方法获取 fragment 的 NavController
同时Activity的左上角ActionBar 有个回退的箭头。非常简单的代码,就能实现了无限切换fragment的布局,不管你有多少个fragment 都能随时切换,完全可以用来单个Activity ,多个 fragment架构APP。以下是Test6_Activity,就是一个 viewpager2,以及Mobile_Fragment 的生命周期监控回调,就是为了在 onResume 的时候取
本文原创,转发请点关注,:)~~~~
viewpager2 中的 fragment 嵌套使用 androidx.navigation.fragment.NavHostFragment
ViewPager2 基础的就不赘述了。
下面这是mobile_fragment 的布局:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="dialog"
android:textSize="30sp" />
<fragment
android:id="@+id/nav_host_fragment_fragment_test6_dialog"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true" /> //注意,不直接设置 setGraph ,放在 java代码中设置,方便灵活切换 Navigation
</LinearLayout>
</layout>
下面是Mobile_Fragment :
public class Mobile_Fragment extends BaseFragment<MobileFragmentBinding> {
@Override
protected int getLayoutId() {
return R.layout.mobile_fragment;
}
@Override
protected void initView() {
Loge.e(this.toString());
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
Test6_Activity test6_activity = (Test6_Activity) context;
getLifecycle().addObserver(test6_activity.new FragmentLifecycle());//监控fragment生命周期
}
@Override
public void onResume() {
super.onResume();
initNav(1);//这里灵活设置 setGraph 方便随时切换 navigation文件,复制布局也可以简单灵活设置。
}
private void initNav(int type) {
NavController controller = Navigation.findNavController(this, R.id.nav_host_fragment_fragment_test6_dialog); //在Activity里获取NavController实例
if (type == 1) {
controller.setGraph(R.navigation.fragment7); //设置xml文件
return;
}
if (type == 2) {
Bundle bundle = new Bundle();
bundle.putString("name", "demo");
controller.setGraph(R.navigation.mobile_navigation); //设置xml文件的并传入数据,这个数据可以在启动的Fragment里获取到
return;
}
if (type == 3) {
controller.setGraph(R.navigation.navigation_dialog); //设置xml文件的并传入数据,这个数据可以在启动的Fragment里获取到
return;
}
finish();
}
@Override
protected void initData() {
}
}
以下 是 navigation文件:
<?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/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="com.android.test2mvvm.test4.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.android.test2mvvm.test4.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" />
<fragment
android:id="@+id/navigation_notifications"
android:name="com.android.test2mvvm.test4.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
</navigation>
以下是Test6_Activity,就是一个 viewpager2,以及Mobile_Fragment 的生命周期监控回调,就是为了在 onResume 的时候取到NavController (在其他生命周期取到的为null)
@Route(path = Constants.TEST6_ACTIVITY)
public class Test6_Activity extends BaseActivity<Test6_ViewModel, Test6ActivityBinding> {
@Override
protected int getContentViewId() {
return R.layout.test6_activity;
}
@Override
protected void processLogic() {
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
List<Fragment> fragmentList = new ArrayList<>();
fragmentList.add(new Mobile_Fragment());
fragmentList.add(new Dialog_Fragment());
fragmentList.add(new Fragment07());
MyViewPager2Adapter myViewPager2Adapter = new MyViewPager2Adapter(this, fragmentList);
binding.viewpager2ActivityTest6.setAdapter(myViewPager2Adapter);
new TabLayoutMediator(binding.tablayoutActivityTest6, binding.viewpager2ActivityTest6, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(fragmentList.get(position).toString());
}
}).attach();
}
NavController navController1;
@Override
public boolean onSupportNavigateUp() {
if (navController1 != null) return navController1.navigateUp();
return super.onSupportNavigateUp();
}
public class FragmentLifecycle implements DefaultLifecycleObserver {
@Override
public void onResume(@NonNull LifecycleOwner owner) {
DefaultLifecycleObserver.super.onResume(owner);
if (owner instanceof Dialog_Fragment) {
Dialog_Fragment dialog_fragment = (Dialog_Fragment) owner;
navController1= Navigation.findNavController(dialog_fragment.getView().findViewById(R.id.nav_host_fragment_fragment_test6_dialog));
}
if (owner instanceof Fragment07) {
Fragment07 fragment07 = (Fragment07) owner;
navController1 = Navigation.findNavController(fragment07.getView().findViewById(R.id.nav_host_fragment_fragment_test6_navigation));
}
if (owner instanceof Mobile_Fragment) {
Mobile_Fragment mobile_fragment = (Mobile_Fragment) owner;
navController1= Navigation.findNavController(mobile_fragment.getView().findViewById(R.id.nav_host_fragment_fragment_test6_mobile));
}
NavigationUI.setupActionBarWithNavController(Test6_Activity.this,navController1);
}
}
}
Test6_Activity 的布局:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/test6_activity_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="test6_activity"
android:textSize="30sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<fragment
android:id="@+id/nav_host_fragment_activity_test6"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="1dp"
app:defaultNavHost="true"
app:layout_constraintTop_toBottomOf="@id/test6_activity_tv" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tablayout_activity_test6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/nav_host_fragment_activity_test6" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager2_activity_test6"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/tablayout_activity_test6"
app:layout_constraintVertical_weight="1" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
最终实现的效果就是,一个ViewPager2内有多个fragment,每个fragment 里面有个NavHostFragment容器,每个容器里面可以放多个fragment 互相跳转(使用Navigation),而且可以随时切换Navigation。同时Activity的左上角ActionBar 有个回退的箭头。非常简单的代码,就能实现了无限切换fragment的布局,不管你有多少个fragment 都能随时切换,完全可以用来 单个Activity ,多个 fragment 架构APP
抓了几张图,大家看效果 :
主要是留意左上角的 箭头。。
更多推荐
所有评论(0)