You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android:实现带BottomNavigationView的单Activity及指定页面隐藏导航栏

基于BottomNavigationView的Android单Activity架构实现

一、核心架构与Fragment切换实现

1. 基础布局搭建

先在主Activity布局中定义Fragment容器和BottomNavigationView:

<?xml version="1.0" encoding="utf-8"?>
<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">

    <!-- Fragment容器 -->
    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toTopOf="@id/bottom_nav"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- 底部导航栏 -->
    <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. 导航菜单配置

在res/menu/bottom_nav_menu.xml中定义导航项:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/nav_home"
        android:icon="@drawable/ic_home"
        android:title="首页"/>
    <item
        android:id="@+id/nav_profile"
        android:icon="@drawable/ic_profile"
        android:title="我的"/>
    <item
        android:id="@+id/nav_payment"
        android:icon="@drawable/ic_payment"
        android:title="支付"/>
</menu>

3. MainActivity核心逻辑

通过FragmentManager处理页面切换,并绑定导航栏点击事件:

class MainActivity : AppCompatActivity() {
    private lateinit var bottomNav: BottomNavigationView
    private lateinit var fragmentContainer: FrameLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        bottomNav = findViewById(R.id.bottom_nav)
        fragmentContainer = findViewById(R.id.fragment_container)

        // 初始化默认页面
        if (savedInstanceState == null) {
            replaceFragment(HomeFragment())
            bottomNav.selectedItemId = R.id.nav_home
        }

        // 导航栏点击事件处理
        bottomNav.setOnItemSelectedListener { menuItem ->
            when (menuItem.itemId) {
                R.id.nav_home -> {
                    replaceFragment(HomeFragment())
                    showBottomNav()
                    true
                }
                R.id.nav_profile -> {
                    replaceFragment(ProfileFragment())
                    showBottomNav()
                    true
                }
                R.id.nav_payment -> {
                    replaceFragment(CardFormFragment())
                    hideBottomNav()
                    true
                }
                else -> false
            }
        }
    }

    // 替换Fragment方法
    private fun replaceFragment(fragment: Fragment) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, fragment)
            .commit()
    }

    // 默认显示导航栏
    private fun showBottomNav() {
        bottomNav.visibility = View.VISIBLE
    }

    // 默认隐藏导航栏
    private fun hideBottomNav() {
        bottomNav.visibility = View.GONE
    }
}

二、BottomNavigationView隐藏的替代方案

除了setVisibility,还有以下几种更灵活的实现方式:

1. 动画过渡隐藏/显示

通过属性动画实现平滑的显示/隐藏效果,提升用户体验:

// 带动画隐藏
private fun hideBottomNavWithAnimation() {
    bottomNav.animate()
        .translationY(bottomNav.height.toFloat())
        .setDuration(300)
        .setListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator?) {}
            override fun onAnimationEnd(animation: Animator?) {
                bottomNav.visibility = View.GONE
            }
            override fun onAnimationCancel(animation: Animator?) {}
            override fun onAnimationRepeat(animation: Animator?) {}
        })
}

// 带动画显示
private fun showBottomNavWithAnimation() {
    bottomNav.visibility = View.VISIBLE
    bottomNav.animate()
        .translationY(0f)
        .setDuration(300)
        .setListener(null)
}

2. 调整布局约束

修改Fragment容器的布局约束,让内容占满屏幕,导航栏移出可视区域:

// 通过约束隐藏导航栏
private fun hideBottomNavByConstraint() {
    val params = fragmentContainer.layoutParams as ConstraintLayout.LayoutParams
    params.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
    fragmentContainer.layoutParams = params
    bottomNav.visibility = View.INVISIBLE
}

// 恢复约束显示导航栏
private fun showBottomNavByConstraint() {
    val params = fragmentContainer.layoutParams as ConstraintLayout.LayoutParams
    params.bottomToBottom = ConstraintLayout.LayoutParams.UNSET
    params.bottomToTop = R.id.bottom_nav
    fragmentContainer.layoutParams = params
    bottomNav.visibility = View.VISIBLE
}

3. 利用Fragment生命周期回调

在目标Fragment的生命周期中通知Activity控制导航栏状态,解耦Activity与Fragment:

// CardFormFragment.kt
class CardFormFragment : Fragment() {
    private var callback: BottomNavControlCallback? = null

    interface BottomNavControlCallback {
        fun hideBottomNav()
        fun showBottomNav()
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        callback = context as? BottomNavControlCallback
    }

    override fun onResume() {
        super.onResume()
        callback?.hideBottomNav()
    }

    override fun onPause() {
        super.onPause()
        callback?.showBottomNav()
    }

    override fun onDetach() {
        super.onDetach()
        callback = null
    }
}

// MainActivity实现接口
class MainActivity : AppCompatActivity(), CardFormFragment.BottomNavControlCallback {
    // ... 其他代码
    override fun hideBottomNav() {
        bottomNav.visibility = View.GONE
        // 也可替换为动画方案
    }

    override fun showBottomNav() {
        bottomNav.visibility = View.VISIBLE
    }
}

三、BottomNavigationView外观自定义方案

1. 修改选中/未选中状态颜色

通过颜色选择器控制图标和文字颜色:

<!-- res/color/bottom_nav_color_selector.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/nav_selected" android:state_selected="true"/>
    <item android:color="@color/nav_unselected"/>
</selector>

<!-- 布局中引用 -->
<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    app:itemIconTint="@color/bottom_nav_color_selector"
    app:itemTextColor="@color/bottom_nav_color_selector"/>

2. 隐藏文字只显示图标

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    app:labelVisibilityMode="unlabeled"/>

3. 自定义MenuItem布局

创建自定义布局并替换默认项:

<!-- res/layout/custom_bottom_nav_item.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="24dp"
        android:layout_height="24dp"/>

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="12sp"
        android:marginTop="2dp"/>
</LinearLayout>

<!-- 布局中引用 -->
<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    app:itemLayout="@layout/custom_bottom_nav_item"/>

4. 修改背景与高度

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    android:background="@drawable/bottom_nav_round_bg"
    android:minHeight="60dp"/>

内容的提问来源于stack exchange,提问作者Nazirjon Kadirov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:12:26