单Activity架构下详情Fragment添加AppBarLayout并保留公共控件的实现问题
实现方案
不需要启动新Activity,完全可以在单Activity架构下基于Navigation Component实现,满足底部导航常驻、详情页独立AppBarLayout的需求,具体步骤如下:
1. 调整Activity布局结构
要保证底部导航全局可见,需要将BottomNavigationView和NavHostFragment放在Activity根布局的同级位置,不要把底部导航组件放到任何Fragment的容器内,示例布局结构:
<!-- Activity根布局用ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- NavHostFragment 占满除底部导航外的所有区域 --> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/bottom_nav" app:navGraph="@navigation/main_nav" /> <!-- 底部导航 固定在屏幕底部 --> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_nav" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:menu="@menu/bottom_nav_menu" /> </androidx.constraintlayout.widget.ConstraintLayout>
2. 控制Activity全局Toolbar的显隐
进入详情页时需要隐藏Activity自带的Toolbar,给详情页的AppBarLayout让出顶部空间,在Activity的onCreate中监听导航目的地变更即可实现:
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController navController.addOnDestinationChangedListener { _, destination, _ -> // 匹配详情页目的地ID,隐藏Activity的Toolbar,其他页面显示 if (destination.id == R.id.detail_fragment) { supportActionBar?.hide() // 如果用的是自定义Toolbar控件,直接修改visibility: // activityToolbar.visibility = View.GONE } else { supportActionBar?.show() // activityToolbar.visibility = View.VISIBLE } }
如果你没有用系统ActionBar,而是自己在Activity布局里加的Toolbar控件,直接修改控件的visibility属性即可。
3. 详情Fragment嵌入独立AppBarLayout
直接在详情Fragment的布局文件中添加你需要的AppBarLayout、CollapsingToolbarLayout等组件即可,示例结构:
<!-- 详情Fragment根布局用CoordinatorLayout支持滚动交互 --> <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/Theme.AppBarOverlay"> <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="200dp" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <!-- 头部自定义内容,比如封面图 --> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/detail_header" /> <androidx.appcompat.widget.Toolbar android:id="@+id/detail_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:theme="@style/Theme.PopupOverlay" /> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <!-- 详情页内容区域,适配滚动交互 --> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <!-- 详情页具体内容 --> </androidx.core.widget.NestedScrollView> </androidx.coordinatorlayout.widget.CoordinatorLayout>
4. 配置详情页Toolbar返回逻辑
在详情Fragment的onViewCreated中给自定义Toolbar设置返回事件即可:
// 设置返回按钮点击逻辑 detail_toolbar.setNavigationOnClickListener { findNavController().popBackStack() } // 按需设置标题 detail_toolbar.title = "详情标题"
补充说明:Google官方底部导航设计指南的演示效果大多也是基于单Activity架构实现,不需要为详情页单独启动Activity,单Activity方案性能更优,也更符合Navigation Component的设计规范。
内容的提问来源于stack exchange,提问作者Erkan
相关产品推荐
相关产品推荐

