单Activity架构的实现----Navigation组件实现Fragment之间的切换

1、关于单Activity架构的好处

对于Activity之间的跳转,往往是通过startActivity来完成跳转,在当前应用进程中,有一个Activity A,它想要跳转到Activity B,其中内部就涉及到了binder机制 + AMS,AMS属于系统进程,也就是说在Activity跳转的时候,在内部其实涉及到了进程间的通信。

对于Binder机制来说,它的显著特点就是会验证身份,这也是相较于Socket通信的优势,它会验证当前要跳转过去的Activity B是不是真的Activity,如果验证是真的,那么就会将B显示出来。

Activity之间的切换浪费那么多的资源,而Fragment就不会;对于Fragment来说,它的内存开销很小,而且Fragment之间不能直接通信,因此耦合性也很低,所以单Activity和多Fragment架构无异于是更好的架构选择,切换界面顺滑。

2、Fragment的切换

既然选择单Activity架构,那么势必就会进行Fragment之间的切换、回退等操作,像Activity这种切换回退操作很简单,但是Fragment之间就不是这个简单的切换操作就能完成。

在之前的架构中,通常使用MainActivity作为容器,保存几个Fragment界面,这样的Fragment界面之间的切换非常简单,但是如果在Fragment界面中,切换到另一个Fragment界面,就涉及到回退栈的问题,在Activity中有任务栈的概念,对于Fragment的回退栈,后面会简单介绍。

3、单Activity架构的实现

(1)在MainActivity中,添加ToolBar + NaviHostFragment + BottomNavigationView,详细的内容见《实现导航栏的几种方式》,其中有实现的详细讲解。
单Activity架构的实现----Navigation组件实现Fragment之间的切换_第1张图片

<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=".MainActivity">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomnavigationview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@android:color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/nav_menu" />

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar"
        app:layout_constraintBottom_toTopOf="@id/bottomnavigationview"
        app:navGraph="@navigation/nav" />

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="?attr/actionBarTheme"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

(2)将所有需要显示的Fragment全部加入NavHost中(注意是全部,不只有主界面显示的4个Fragment),在主界面中配置导航。

		bottomnavigationview = findViewById(R.id.bottomnavigationview);
        toolbar = findViewById(R.id.toolbar);
        //随着底部导航按钮点击移动
        NavController controller = Navigation.findNavController(this, R.id.fragment);
        NavigationUI.setupWithNavController(bottomnavigationview,controller);
        //消除back按键,随着点击改变ToolBar显示
        AppBarConfiguration configuration = new AppBarConfiguration.Builder(bottomnavigationview.getMenu()).build();
        NavigationUI.setupWithNavController(toolbar,controller,configuration);

(3)Fragment页面跳转

当点击Fragment界面中的按钮,跳转到另一个Fragment界面时,需要在nav中来设置方向。

单Activity架构的实现----Navigation组件实现Fragment之间的切换_第2张图片

 <fragment
        android:id="@+id/shopFragment"
        android:name="com.example.singleactivity.fragment.ShopFragment"
        android:label="ShopFragment" >
        <action
            android:id="@+id/action_shopFragment_to_fragment1"
            app:destination="@id/fragment1" />
    </fragment>

这个时候,在XML文件中,出现action属性,id代表方向,从shopFragment到fragment1,destination代表目的地,为fragment1。

当点击跳转的时候,这个action就起到作用了。

 //点击进入下一界面
        btn_enter1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Navigation.findNavController(v)
                        .navigate(R.id.action_shopFragment_to_fragment1);
            }
        });

方式1:通过findNavController,找到对应的导航容器,调用navigate方法,传入对应的action,便可跳转到对应的Fragment

 btn_enter1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {   			
            	Navigation.createNavigateOnClickListener(R.id.action_shopFragment_to_fragment1).onClick(v);
            }
        });

方式2:通过createNavigateOnClickListener,传入对应的action,调用onClick方法,同样可以响应点击事件,跳转到对用的Fragment

你可能感兴趣的:(单Activity架构的实现----Navigation组件实现Fragment之间的切换)