如何隐藏Bottom Navigation Bar?实现类似YouTube横屏的自动隐藏全屏效果
Android 实现底部导航栏透明/自动隐藏(仿YouTube横屏效果)
一、设置底部导航栏透明,让内容全屏显示
如果是系统原生导航栏,可通过以下两种方式设置透明,让布局延伸到导航栏下方:
方法1:主题配置(静态)
在res/values/styles.xml中定义全屏主题:
<style name="AppTheme.FullScreen" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <!-- 允许布局延伸到系统栏区域 --> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> <item name="android:windowTranslucentNavigation">true</item> <item name="android:navigationBarColor">@android:color/transparent</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> </style>
随后在AndroidManifest.xml中给目标Activity指定该主题即可。
方法2:代码动态设置(灵活)
在Activity的onCreate()方法中添加逻辑:
private fun setupTransparentNav() { window.apply { // 允许布局延伸到导航栏下方 setFlags( WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS ) // 设置导航栏完全透明 navigationBarColor = Color.TRANSPARENT // 避免导航栏状态切换时布局跳动 decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE } }
二、实现自动隐藏/显示(仿YouTube横屏交互)
针对系统原生导航栏
利用系统WindowInsetsController可快速实现「上滑唤起、无操作自动隐藏」的效果:
private fun setupAutoHideSystemNav() { val insetsController = ViewCompat.getWindowInsetsController(window.decorView) ?: return // 设置导航栏行为:滑动时临时显示,闲置时自动隐藏 insetsController.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE // 初始进入页面时隐藏导航栏 insetsController.hide(WindowInsetsCompat.Type.navigationBars()) }
这种方式完全匹配YouTube横屏逻辑:用户从底部上滑即可唤起导航栏,几秒无操作后自动隐藏,无需额外手写手势判断。
针对自定义BottomNavigationView
如果是自行实现的底部导航栏,可通过动画+手势监听完成交互:
private fun setupAutoHideCustomNav() { val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav) val contentView = findViewById<FrameLayout>(R.id.content_container) var isNavVisible = true // 给内容区域添加触摸监听,点击/滑动时切换导航栏状态 contentView.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_UP) { toggleNavVisibility(bottomNav, isNavVisible) isNavVisible = !isNavVisible // 切换显示后启动自动隐藏倒计时 startAutoHideTimer(bottomNav) { isNavVisible = it } } true } } // 导航栏显示/隐藏动画 private fun toggleNavVisibility(nav: BottomNavigationView, isVisible: Boolean) { val targetY = if (isVisible) nav.height.toFloat() else 0f nav.animate().translationY(targetY).setDuration(300).start() } // 自动隐藏倒计时(3秒无操作后隐藏) private fun startAutoHideTimer(nav: BottomNavigationView, statusCallback: (Boolean) -> Unit) { Handler(Looper.getMainLooper()).postDelayed({ nav.animate().translationY(nav.height.toFloat()).setDuration(300).start() statusCallback(false) }, 3000) }
注意事项
- 若内容被导航栏遮挡,可给根布局添加
android:fitsSystemWindows="false",或动态设置底部padding:
// 获取导航栏高度,给内容布局添加底部内边距 val navHeight = resources.getDimensionPixelSize(R.dimen.design_bottom_navigation_height) contentView.setPadding(0, 0, 0, navHeight)
- 横竖屏切换时,需重新调用配置方法,避免状态失效。
内容的提问来源于stack exchange,提问作者Ayush Sinha
相关产品推荐
相关产品推荐

