uni-app 设置 Android 底部虚拟导航栏背景色

在 uni-app 项目中,如果运行到 App 端,Android 手机底部可能会出现系统虚拟按键栏,也就是返回、主页、多任务所在的那一块区域。这个区域不属于页面 DOM,也不是 uni-app 的 tabBar,所以不能通过普通 CSS 直接修改。

要修改它的背景色,需要调用 Android 原生能力。

一、适用范围

这个方案只适用于:

复制代码
APP-PLUS + Android

不适用于:

css 复制代码
H5
微信小程序
支付宝小程序
iOS

iOS 没有 Android 这种底部虚拟按键栏。如果想控制 iPhone 底部 Home Indicator 附近的颜色,需要设置页面背景或底部安全区容器背景。

二、核心方案

Android 原生设置底部虚拟导航栏颜色的方法是:

javascript 复制代码
window.setNavigationBarColor(colorInt)

在 uni-app 里,可以通过 Native.js 调用:

arduino 复制代码
const color = plus.android.newObject('android.graphics.Color')
const activity = plus.android.runtimeMainActivity()
const window = plus.android.invoke(activity, 'getWindow')
const colorInt = plus.android.invoke(color, 'parseColor', '#000000')
plus.android.invoke(window, 'setNavigationBarColor', colorInt)

三、推荐封装

可以抽成公共工具函数,例如:

typescript 复制代码
// src/utils/navigationBar.ts
declare const plus: any

/** 设置安卓底部导航栏颜色 */
export const setAndroidNavigationBarColor = (colorValue = '#000000') => {
  // #ifdef APP-PLUS
  if (uni.getSystemInfoSync().platform !== 'android') return

  try {
    const Build = plus.android.importClass('android.os.Build')
    if (Build.VERSION.SDK_INT < 21) return

    const color = plus.android.newObject('android.graphics.Color')
    const activity = plus.android.runtimeMainActivity()
    const window = plus.android.invoke(activity, 'getWindow')
    const colorInt = plus.android.invoke(color, 'parseColor', colorValue)

    plus.android.invoke(window, 'setNavigationBarColor', colorInt)
  } catch (error) {
    console.warn('设置安卓底部导航栏颜色失败', error)
  }
  // #endif
}

四、页面中使用

比如登录页需要设置成黑色:

javascript 复制代码
import { onShow } from '@dcloudio/uni-app'
import { setAndroidNavigationBarColor } from '@/utils/navigationBar'

onShow(() => {
  setAndroidNavigationBarColor('#000000')
})

如果其他页面需要设置成白色:

scss 复制代码
onShow(() => {
  setAndroidNavigationBarColor('#ffffff')
})

建议放在 onShow,因为页面切换回来时可以重新设置,避免被其他页面覆盖。

五、为什么不用直接调用

下面这种写法可能会报错:

ini 复制代码
const Color = plus.android.importClass('android.graphics.Color')
const main = plus.android.runtimeMainActivity()
const window = main.getWindow()

window.setNavigationBarColor(Color.parseColor('#000000'))

常见错误包括:

arduino 复制代码
Cannot read property 'parseColor' of undefined

或:

vbnet 复制代码
setNavigationBarColor is not a function

原因是 Native.js 里的 Java 对象代理不一定能像普通 JS 对象一样直接调用方法。更稳妥的方式是使用:

arduino 复制代码
plus.android.invoke(...)

六、不要调用 setTabBarStyle

有些示例里可能会写:

arduino 复制代码
plus.android.invoke(window, 'setTabBarStyle', colorInt)

这个不建议保留。

Android 原生 Window 没有 setTabBarStyle 这个方法,大概率无效,甚至可能报错。设置底部虚拟按键栏只需要:

复制代码
setNavigationBarColor

七、iOS 怎么办

iOS 没有 Android 这种虚拟导航栏 API。iPhone 底部 Home Indicator 区域的颜色来自页面背景或底部容器背景。

可以通过 CSS 控制:

css 复制代码
page {
  background: #ffffff;
}

如果页面有底部固定按钮:

css 复制代码
.footer {
  padding-bottom: env(safe-area-inset-bottom);
  background: #ffffff;
}

八、最终建议

如果项目只需要全局固定一个颜色,可以优先在 manifest 里配置 Android 的 navigationBarColor

如果不同页面需要不同颜色,推荐使用本文的工具函数,在页面 onShow 中动态设置。

最终实践方案:

复制代码
manifest 配默认色
页面 onShow 动态覆盖
iOS 通过页面背景和安全区背景处理

这样兼容性更好,也更方便维护。

相关推荐
JeffongTan11 分钟前
在LWC中镶嵌VF Page获取用户IP
前端·javascript·salesforce
91刘仁德2 小时前
MYSQL 事务原理及使用
android·mysql·adb
陆枫Larry2 小时前
Astro 是什么
前端
一笑的小酒馆3 小时前
AndroidKMP之瀑布流实现
android
RainyJiang3 小时前
AI时代下,Android的边界正在消失
android·openai·ai编程
是立不是利4 小时前
写给设计师的 CSS 博客美学指南
前端·css
Android-Flutter4 小时前
android 内存抖动详解
android
默_笙5 小时前
🏝 Docker 就是"房地产开发":从施工图纸到小区物业的容器化指南
前端·javascript
计算机魔术师5 小时前
Rohan Paul 谈用时间跨度衡量智能体能力,并引用 OpenAI 自动化研究实习生里程碑
前端
kyriewen5 小时前
我手写了个极简版 React Router——才搞懂 v6 为什么砍了这么多 API
前端·javascript·程序员