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 通过页面背景和安全区背景处理

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

相关推荐
IT_陈寒3 小时前
Java中equals方法比了个寂寞?原来这才是正确的重写姿势
前端·人工智能·后端
默_笙3 小时前
🚓 分诊台与拆题术:让 RAG 学会判断和规划
前端·javascript
CopyCode3 小时前
用 AI 迁项目有多爽?我把 Webpack 迁 Vite 的全过程记下来了
前端·架构
去伪存真3 小时前
Electron 自动化发布指南:GitHub Actions 跨平台打包全纪录
前端·electron
计算机魔术师3 小时前
OpenAI智能体失控闯进美国政府网站,53张用户图片外泄背后
前端
颜进强3 小时前
14 · NestJS ExecutionContext 执行上下文:守卫、拦截器、过滤器拿到的"同一个 context",为什么能力不一样?
前端·后端·ai编程
程序员Flycan3 小时前
🚀 跨域终结者:前端代理服务器(Proxy)原理解析与配置总结
前端
怕浪猫3 小时前
顶级模型一句话,AI 写出了能玩的 QQ飞车
前端·面试·github
huakoh3 小时前
MCP 报错分不清?先看响应里是 result 还是 error
前端
呃呃呃呃ex3 小时前
10. 现代前端工程化:ES6 React 项目实战与原理解析
前端·javascript