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

如何让Bottom Navigation Bar在Activity切换时保持固定不移动?

解决Bottom Navigation Bar切换时随页面移动的问题

你当前的问题根源是多Activity架构下,页面切换动画会作用于整个Activity窗口,包括每个Activity里的Bottom Navigation Bar,所以切换时导航栏会跟着动。最合理的解决方案是改用单Activity + Fragment架构,把三个页面做成Fragment,导航栏固定在主Activity中,只切换Fragment内容区域。

具体实现步骤

1. 将原Activity改为Fragment

把SettingsActivity和StatsActivity重构为SettingsFragment、StatsFragment,示例代码:

class SettingsFragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_settings, container, false)
    }
}

2. 调整主Activity布局

让Bottom Navigation Bar固定在底部,上方用Fragment容器承载页面内容(示例布局activity_main.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical">

    <!-- Fragment容器,占满除导航栏外的所有空间 -->
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <!-- 固定在底部的导航栏 -->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/bottom_nav_menu" />

</LinearLayout>

3. 修改主Activity代码,实现Fragment切换

不再启动新Activity,而是切换Fragment,并给Fragment切换添加动画:

class MainActivity : AppCompatActivity() {
    private lateinit var navbar: BottomNavigationView

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

        navbar = findViewById(R.id.bottom_navigation)

        // 初始化默认加载首页Fragment
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragment_container, HomeFragment())
                .commit()
        }

        navbar.setOnItemSelectedListener { item ->
            val transaction = supportFragmentManager.beginTransaction()

            // 根据切换方向设置Fragment动画
            transaction.setCustomAnimations(
                when (item.itemId) {
                    R.id.ic_settings -> R.anim.slide_from_left
                    R.id.ic_stats -> R.anim.slide_from_right
                    else -> 0
                },
                when (item.itemId) {
                    R.id.ic_settings -> R.anim.slide_to_right
                    R.id.ic_stats -> R.anim.slide_to_left
                    else -> 0
                }
            )

            // 替换对应Fragment
            when (item.itemId) {
                R.id.ic_home -> transaction.replace(R.id.fragment_container, HomeFragment())
                R.id.ic_settings -> transaction.replace(R.id.fragment_container, SettingsFragment())
                R.id.ic_stats -> transaction.replace(R.id.fragment_container, StatsFragment())
            }

            transaction.commit()
            true
        }
    }
}

为什么这个方案有效?

  • 主Activity中的Bottom Navigation Bar属于固定布局,不会参与Fragment的切换动画,始终保持在底部不动。
  • 只有Fragment容器内的内容会执行滑动动画,完全符合你的需求。

备选方案(不推荐)

如果实在不想重构为Fragment,可以尝试修改动画文件,指定动画仅作用于Activity的内容区域:

  1. 给每个Activity的内容区域设置唯一ID(比如content_container)。
  2. 修改动画文件,添加android:targetId="@id/content_container",示例slide_from_left.xml:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-100%"
    android:toXDelta="0%"
    android:duration="300"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:targetId="@id/content_container" />

这种方式需要每个Activity都调整布局和动画,维护成本高,且可能存在窗口切换的细微痕迹,不如Fragment架构优雅。

内容的提问来源于stack exchange,提问作者Kiss Gergő

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:20:34