如何在Fragment中隐藏Toolbar?折叠CollapsingToolbar时隐藏主Toolbar与Pager工具栏
嗨,这个场景我之前做项目的时候碰到过,刚好有几个可行的方案可以帮你解决,一起来看看:
解决方案
核心思路是监听CollapsingToolbarLayout所在的AppBarLayout滚动偏移状态,根据折叠的百分比来控制主Toolbar和FragmentPager的Toolbar显示/隐藏。
1. 监听AppBarLayout的滚动偏移
在包含CollapsingToolbar的Fragment中,给AppBarLayout添加滚动偏移监听器,通过计算折叠百分比判断何时触发Toolbar的隐藏/显示:
Kotlin 示例
val appBarLayout = view.findViewById<AppBarLayout>(R.id.app_bar_layout) appBarLayout.addOnOffsetChangedListener { _, verticalOffset -> // 计算折叠完成度(0=完全展开,1=完全折叠) val totalScrollRange = appBarLayout.totalScrollRange val collapseRate = Math.abs(verticalOffset).toFloat() / totalScrollRange.toFloat() // 当完全折叠时,隐藏目标Toolbar;展开时恢复显示 if (collapseRate >= 1f) { // 通知Activity隐藏主Toolbar (activity as? MainActivity)?.hideMainToolbar() // 隐藏FragmentPager的Toolbar(假设你已拿到该Toolbar实例) pagerToolbar.visibility = View.GONE } else { (activity as? MainActivity)?.showMainToolbar() pagerToolbar.visibility = View.VISIBLE } }
Java 示例
AppBarLayout appBarLayout = view.findViewById(R.id.app_bar_layout); appBarLayout.addOnOffsetChangedListener((appBar, verticalOffset) -> { int totalScrollRange = appBar.getTotalScrollRange(); float collapseRate = Math.abs(verticalOffset) / (float) totalScrollRange; if (collapseRate >= 1f) { if (getActivity() instanceof MainActivity) { ((MainActivity) getActivity()).hideMainToolbar(); } pagerToolbar.setVisibility(View.GONE); } else { if (getActivity() instanceof MainActivity) { ((MainActivity) getActivity()).showMainToolbar(); } pagerToolbar.setVisibility(View.VISIBLE); } });
2. 在Activity中实现Toolbar的平滑过渡
为了让Toolbar的显示/隐藏更流畅,推荐用动画替代直接设置可见性,在主Activity中添加两个公开方法:
Kotlin 示例
// MainActivity.kt fun hideMainToolbar() { mainToolbar.animate() .translationY(-mainToolbar.height.toFloat()) .setDuration(300) .start() } fun showMainToolbar() { mainToolbar.animate() .translationY(0f) .setDuration(300) .start() }
Java 示例
// MainActivity.java public void hideMainToolbar() { mainToolbar.animate() .translationY(-mainToolbar.getHeight()) .setDuration(300) .start(); } public void showMainToolbar() { mainToolbar.animate() .translationY(0) .setDuration(300) .start(); }
3. 优化:解耦Fragment与Activity的通信
如果不想用强转Activity的方式,推荐用ViewModel实现跨组件通信,代码更健壮:
- 创建共享ViewModel:
class ToolbarControlViewModel : ViewModel() { val isToolbarVisible = MutableLiveData<Boolean>(true) }
- 在主Activity中观察状态:
val viewModel = ViewModelProvider(this)[ToolbarControlViewModel::class.java] viewModel.isToolbarVisible.observe(this) { isVisible -> if (isVisible) showMainToolbar() else hideMainToolbar() }
- 在Fragment中更新状态:
val viewModel = ViewModelProvider(requireActivity())[ToolbarControlViewModel::class.java] // 在AppBar偏移监听中更新 viewModel.isToolbarVisible.value = collapseRate < 1f
注意事项
- 可以根据UI需求调整折叠阈值,比如当
collapseRate >= 0.8f时就开始隐藏Toolbar,不用等完全折叠。 - 确保获取Toolbar实例时避免空指针,比如用
findViewById前先判断视图是否初始化完成。
内容的提问来源于stack exchange,提问作者user9646251
相关产品推荐
相关产品推荐

