Android悬浮WebView加载Home Assistant深色模式启动页异常
解决Android悬浮WebView(API28)中Home Assistant启动页深色模式异常问题
问题核心
全屏WebView加载Home Assistant时启动页正常显示深色,但通过WindowManager实现的悬浮WebView启动页为浅色,最终页面可正常显示深色。HA官方说明启动页的深浅由浏览器设置决定,因此需为悬浮WebView配置深色环境。
原因分析
全屏WebView继承了Activity的主题配置,默认适配深色模式;而悬浮WebView是通过WindowManager添加的独立视图,未继承Activity的深色主题,WebView默认使用浅色环境,导致HA启动页加载浅色样式。
解决方案(适配API28)
由于API28不支持WebView的setForceDark等深色模式专属API,需通过视图层级配置+JS注入的方式模拟深色浏览器环境:
1. 为悬浮视图容器设置深色背景
在添加父容器到WindowManager前,设置黑色背景,避免WebView加载前显示空白白色:
mParentView = FrameLayout(this) mParentView.setBackgroundColor(Color.BLACK) // 添加这一行 windowManager.addView(mParentView, floatWindowLayoutParam)
2. 让WebView继承容器主题上下文
Inflate布局时传入父容器,确保WebView获取到正确的主题环境:
// 替换原inflate代码,传入mParentView作为父容器 floatView = inflater.inflate(R.layout.widget_web, mParentView, false) as ViewGroup
3. 配置WebView背景并注入JS强制深色模式
设置WebView自身背景为黑色,并在页面启动时注入JS,让HA识别到深色环境:
myWebView = floatView.findViewById(R.id.web_view) as WebView myWebView.setBackgroundColor(Color.BLACK) // 设置WebView深色背景 // 配置WebViewClient,在页面启动时注入JS myWebView.webViewClient = object : WebViewClient() { override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) view?.evaluateJavascript( "(function() { " + "document.documentElement.style.setProperty('color-scheme', 'dark only'); " + "if (window.matchMedia) { " + "window.matchMedia('(prefers-color-scheme: dark)').matches = true; " + "} " + "})()", null ) } }
修改后的完整悬浮WebView代码
lateinit var windowManager: WindowManager lateinit var floatView: ViewGroup lateinit var mParentView: ViewGroup lateinit var floatWindowLayoutParam: WindowManager.LayoutParams setContentView(R.layout.widget_web) floatWindowLayoutParam = WindowManager.LayoutParams( 1000,1000, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT ) windowManager = getSystemService(WINDOW_SERVICE) as WindowManager val inflater: LayoutInflater = baseContext.getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater mParentView = FrameLayout(this) mParentView.setBackgroundColor(Color.BLACK) windowManager.addView(mParentView, floatWindowLayoutParam) floatView = inflater.inflate(R.layout.widget_web, mParentView, false) as ViewGroup floatView.visibility = View.GONE mParentView.addView(floatView) myWebView = floatView.findViewById(R.id.web_view) as WebView myWebView.setBackgroundColor(Color.BLACK) myWebView.settings.javaScriptEnabled = true myWebView.settings.domStorageEnabled = true myWebView.setInitialScale(100) myWebView.addJavascriptInterface(WebViewJavascriptInterface(applicationContext), "externalApp") myWebView.webViewClient = object : WebViewClient() { override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) view?.evaluateJavascript( "(function() { " + "document.documentElement.style.setProperty('color-scheme', 'dark only'); " + "if (window.matchMedia) { " + "window.matchMedia('(prefers-color-scheme: dark)').matches = true; " + "} " + "})()", null ) } } myWebView.loadUrl("http://192.168.1.73:8123/dashboard-studyonly?external_auth=1") myWebView.requestFocus() myWebView.visibility = View.VISIBLE finish()
注意事项
- 测试前需清除WebView缓存,避免旧的偏好设置干扰结果
- 确保Home Assistant后台已开启全局深色模式
- API28及以下版本无法使用WebView原生深色模式API,上述方案是兼容该版本的最优解
内容的提问来源于stack exchange,提问作者Bailey
相关产品推荐
相关产品推荐

