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

如何实现屏幕旋转时BottomNavigationView固定位置并旋转图标?

实现BottomNavigationView横竖屏自适应位置与旋转效果

要实现竖屏时顶部导航、横屏时左侧导航且图标文字适配旋转的效果,可通过布局资源适配+代码动态调整视图属性来完成,具体步骤如下:

1. 配置横竖屏布局资源

Android支持按屏幕方向加载不同布局,我们分别创建两种布局:

竖屏布局(res/layout/activity_main.xml)

保持BottomNavigationView在顶部,宽度铺满屏幕:

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/transparent"
    app:elevation="0dp"
    app:itemBackground="@color/transparent"
    app:itemIconTint="@drawable/selector"
    app:itemTextColor="@drawable/selector"
    app:labelVisibilityMode="labeled"
    app:menu="@menu/nav_menu" />

横屏布局(res/layout-land/activity_main.xml)

将BottomNavigationView放在左侧,高度铺满屏幕,后续通过代码处理旋转:

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_bar"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:background="@color/transparent"
    app:elevation="0dp"
    app:itemBackground="@color/transparent"
    app:itemIconTint="@drawable/selector"
    app:itemTextColor="@drawable/selector"
    app:labelVisibilityMode="labeled"
    app:menu="@menu/nav_menu" />

2. 代码动态处理视图旋转与布局

在Activity中监听屏幕方向变化,调整导航栏的旋转角度和布局参数,同时添加平滑过渡动画:

步骤1:配置Activity监听方向变化

在AndroidManifest.xml对应Activity中添加属性,避免旋转时重建页面:

<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize">
</activity>

步骤2:实现方向变化逻辑

在Activity中重写onConfigurationChanged方法:

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    val navBar = findViewById<BottomNavigationView>(R.id.nav_bar)
    val targetRotation = if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) 270f else 0f
    val layoutParams = navBar.layoutParams

    // 平滑旋转动画
    ObjectAnimator.ofFloat(navBar, View.ROTATION, navBar.rotation, targetRotation).apply {
        duration = 300
        interpolator = AccelerateDecelerateInterpolator()
        start()
    }

    // 调整布局参数
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT
        layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
        // 若使用ConstraintLayout,设置约束到左侧、顶部、底部
        (layoutParams as? ConstraintLayout.LayoutParams)?.apply {
            startToStart = ConstraintLayout.LayoutParams.PARENT_ID
            topToTop = ConstraintLayout.LayoutParams.PARENT_ID
            bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID
            endToEnd = ConstraintLayout.LayoutParams.UNSET
        }
    } else {
        layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
        layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
        (layoutParams as? ConstraintLayout.LayoutParams)?.apply {
            topToTop = ConstraintLayout.LayoutParams.PARENT_ID
            startToStart = ConstraintLayout.LayoutParams.PARENT_ID
            endToEnd = ConstraintLayout.LayoutParams.PARENT_ID
            bottomToBottom = ConstraintLayout.LayoutParams.UNSET
        }
    }
    navBar.layoutParams = layoutParams

    // 保存并恢复选中状态,避免旋转后丢失
    val selectedItemId = navBar.selectedItemId
    navBar.selectedItemId = selectedItemId
}

3. 优化菜单项显示(可选)

默认菜单项在旋转后文字方向可能不符合预期,可自定义item布局调整显示逻辑:

创建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="match_parent"
    android:orientation="vertical"
    android:gravity="center">

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

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

在Activity的onCreate中设置自定义布局:

val navBar = findViewById<BottomNavigationView>(R.id.nav_bar)
for (i in 0 until navBar.menu.size()) {
    navBar.setItemView(i, LayoutInflater.from(this).inflate(R.layout.custom_bottom_nav_item, navBar, false))
}

4. 关键注意点

  • 若使用Java,将上述Kotlin代码转换为对应语法即可
  • 测试不同分辨率设备,避免布局错位
  • 若需要更精细的文字方向控制,可在自定义item布局中根据屏幕方向动态调整文字旋转角度

内容的提问来源于stack exchange,提问作者Do Ji

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 07:54:20