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

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

相关推荐
TechNomad1 小时前
Kotlin类对象与接口详解
android·kotlin
金色的暴发户1 小时前
一劳永逸解决Codex手机验证
前端·人工智能·开源
DanCheOo2 小时前
AI 应用的可观测性:你的 AI 系统在生产上到底表现怎么样
前端·openai
Hyyy2 小时前
流式渲染用react-markdown还是Vercel/Streamdown
前端
风中的小甜瓜2 小时前
ASP.NET Page 那点事
java·前端·asp.net
木西2 小时前
告别机械重复:使用 Node.js + Playwright 构建 24 小时全自动测试网领水脚本
前端·javascript·node.js
西柚小萌新2 小时前
【论文写作】--LaTeX详细入门教程2
前端·html
qdkfz2 小时前
JavaScript 如何解析 Outlook .msg 文件 —— @kenjiuno/msgreader
前端·javascript
LuckyDog阿祥3 小时前
卸载Microsoft Edge:EdgeRemover完整操作指南
前端·edge