【2025年4月18日】android studiio最新设置沉浸式状态栏教程

😫【2025年4月18日】搞了一整天,终于完美搞定 Android 沉浸式状态栏(WebView + 本地HTML)

最近在做一个个人项目,用 Android 加载本地 HTML 做个小工具。按理说用 WebView 加载页面很简单嘛——结果沉浸式状态栏这个坑,属实给我干破防了……

🕳️ 坑1:状态栏怎么都不透明

🕳️ 坑2:透明了但网页内容被遮住

🕳️ 坑3:参考了N篇博客,全是复制粘贴,没一个能跑通!

搞了一天一夜,终于悟了,自己亲手撸出来一个真正完美兼容 WebView 的沉浸式状态栏方案。写这篇就是为了拯救和我一样被状态栏折磨的开发者们 🙃


🌈 最终效果(说人话)

  • 状态栏透明 ✅
  • 页面内容不被遮挡 ✅
  • 支持动态适配状态栏高度 ✅
  • 全部代码简洁明了,不用配置一堆神秘 style ✅

🧠 我的解决方案

  1. 把状态栏设成透明(但不隐藏);
  2. 把 WebView 填充到全屏;
  3. 加载网页后,动态设置 HTML 顶部的 padding-top,让内容往下移动,刚好避开状态栏!

🧪 完整代码(就是这货,拯救了我)

📄 MainActivity.kt

package com.example.testimport android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.View
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity@Suppress("DEPRECATION")
class MainActivity : AppCompatActivity() {private lateinit var webView: WebViewprivate var doubleBackToExitPressedOnce = false@SuppressLint("SetJavaScriptEnabled")override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREENor View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)window.statusBarColor = Color.TRANSPARENTwebView = WebView(this)setContentView(webView)val webSettings = webView.settingswebSettings.javaScriptEnabled = truewebSettings.loadsImagesAutomatically = truewebSettings.domStorageEnabled = truewebSettings.cacheMode = WebSettings.LOAD_DEFAULTwebSettings.allowFileAccess = truewebSettings.allowFileAccessFromFileURLs = truewebSettings.allowUniversalAccessFromFileURLs = truewebSettings.useWideViewPort = truewebSettings.loadWithOverviewMode = true// 防止跳转到外部浏览器webView.webViewClient = WebViewClient()webView.webViewClient = object : WebViewClient() {override fun onPageFinished(view: WebView?, url: String?) {val height = getStatusBarHeight()webView.evaluateJavascript("document.getElementsByClassName('header')[0].style.paddingTop ='${height}px';",null)}}// 加载本地 HTMLwebView.loadUrl("file:///android_asset/index.html")}override fun onBackPressed() {if (webView.canGoBack()) {webView.goBack()} else {if (doubleBackToExitPressedOnce) {super.onBackPressed()return}this.doubleBackToExitPressedOnce = trueToast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show()Handler(Looper.getMainLooper()).postDelayed({doubleBackToExitPressedOnce = false}, 2000)}}@SuppressLint("DiscouragedApi")fun getStatusBarHeight(): Double {val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")val px = if (resourceId > 0) resources.getDimensionPixelSize(resourceId) else 0val density = resources.displayMetrics.densityval dp = (px / density).toInt() // 转为逻辑像素return dp*1.2 // 多乘点,保险一点}}

🎨 res/values/themes.xml

<resources xmlns:tools="http://schemas.android.com/tools"><style name="Theme.Test" parent="Theme.AppCompat.NoActionBar"><item name="android:windowNoTitle">true</item><item name="android:windowFullscreen">true</item><item name="windowActionBar">false</item></style>
</resources>


🧩 遇到的几个“小坑提示”

  • 状态栏高度是 px,要转成 dp 后加到网页上才舒服,不然有时显示偏差一丢丢。
  • document.getElementsByClassName('header')[0].style.paddingTop ='${height}px';请根据自己的网页内容来修改(比如给body设置,而不是我这边的.header的class)

✌️ 总结

就这么简单几步,我终于实现了一个:

  • 沉浸式状态栏 ✅
  • 本地网页不被遮挡 ✅
  • 页面美观可控 ✅
  • 脚本注入可调节 ✅

如果你正好也在做类似项目,希望这篇能给你节省几个小时人生!


📣 如果你觉得有用

点个赞 ⭐ 收藏一下 💾
关注我,后面会继续分享更多原生 + 前端混合开发的踩坑记录!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/901923.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何删除 Launchpad 中 Chrome 的图标

有一天突然在 Launchpad 中出现下面的图标&#xff0c;在 Finder 的 Applications 中也没有&#xff0c;不知道如何删除。最终在《How to remove chrome app icons from launchpad?》中找到了答案。中文互联网上并没有搜到相关帖子&#xff0c;遂作记录。 解决办法很简单&am…

PHP8.2.9NTS版本使用composer报错,扩展找不到的问题处理

使用composer install时报错&#xff1a; The openssl extension is required for SSL/TLS protection but is not available. If you can not enable the openssl extension, you can disable this error, at y our own risk, by setting the ‘disable-tls’ option to true.…

一本通 2063:【例1.4】牛吃牧草 1005:地球人口承载力估计

Topic&#xff1a; Ideas&#xff1a; 为什么把这两道题放在一起呢&#xff1f;就是因为这两道题很类似&#xff0c;都是很简单的数学题&#xff0c;只要你会列出数学等式&#xff0c;你就学会这道题了&#xff01; 下面把计算过程展示给大家 Code&#xff1a; //2025/04/18…

基于用户的协同过滤推荐系统实战项目

文章目录 基于用户的协同过滤推荐系统实战项目1. 推荐系统基础理论1.1 协同过滤概述1.2 基于用户的协同过滤原理1.3 相似度计算方法1.3.1 余弦相似度(Cosine Similarity)1.3.2 皮尔逊相关系数(Pearson Correlation)1.3.3 欧几里得距离(Euclidean Distance)1.3.4 调整余弦相似度…

【SpringBoot】基于Filter实现SQL注入过滤器

最近扫出了一个SQL注入安全漏洞&#xff0c;用户的非法输入可能导致数据泄露、数据篡改甚至系统崩溃&#xff0c;为了有效防范 SQL 注入攻击&#xff0c;除了在代码层面使用参数化查询和预编译语句外&#xff0c;还可以通过实现一个Filter来过滤掉潜在的危险输入。本文将介绍如…

Spring Boot 项目里设置默认国区时区,Jave中Date时区配置

在 Spring Boot 项目里设置国区时区&#xff08;也就是中国标准时间&#xff0c;即 Asia/Shanghai&#xff09;&#xff0c;可通过以下几种方式实现&#xff1a; 方式一&#xff1a;在application.properties或application.yml里设置 application.properties properties sp…

Python环境中在线训练机器学习模型所遇到的问题及解决方案

我最近开发个智能控制系统,包括实时数据采集、预测、策略优化等功能,最近增加在线学习功能,也就是在线进行模型训练,在线进行模型训练时出现了问题,现象为: 控制台报: cmdstanpy - INFO - Chain [1] start processing所有任务、线程停止,Web服务登录无法访问后台的pyt…

【教程】无视硬件限制强制升级Windows 11

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 1、下载升级工具&#xff1a;https://github.com/builtbybel/Flyby11/releases 2、解压后打开软件&#xff1a; 3、拖入win11.iso或者自动下载&#xf…

麦科信汽车诊断示波器在机车维修领域中的应用实例

麦科信汽车诊断示波器在机车维修领域中的应用实例 “Micsig SATO1004的错误帧统计功能与历史波形存储&#xff0c;让我们在诊断间歇性CAN故障时有了决定性武器。这不仅是工具升级&#xff0c;更是维修理念的革新。” — Ian Coffey, Mototek技术总监&#xff08;欧洲ECU诊…

【IDEA2020】 解决开发时遇到的一些问题

目录 一、批量更新数据库数据 逐条更新 Db.updateEntitiesBatch() 二、Error running&#xff0c;Command line is too long. Shorten command line 报错场景 报错分析 解决方法 一、批量更新数据库数据 逐条更新 List<UserModel> ums userMapper.selectListBy…

算法01-最小生成树prim算法

最小生成树prim算法 题源&#xff1a;代码随想录卡哥的题 链接&#xff1a;https://kamacoder.com/problempage.php?pid1053 时间&#xff1a;2025-04-18 难度&#xff1a;4⭐ 题目&#xff1a; 1. 题目描述&#xff1a; 在世界的某个区域&#xff0c;有一些分散的神秘岛屿&…

cpolar 内网穿透 实现公网可以访问本机

1、登录网站&#xff0c;升级成专业版&#xff0c;测试的话建议选一个月付费&#xff0c;选择预留 2、保留的TCP地址增加一条记录&#xff0c;描述可以自己取 3、验证&#xff0c;生成一个Authtocken码 4、在安装目录下&#xff0c;打开CMD命令&#xff0c;复制上面的码运行aut…

c#内存泄露的原因和解决办法

内存泄漏的原因 不正确的对象引用&#xff1a;最常见的原因是对象不再需要时未被垃圾回收器回收。例如&#xff0c;如果一个对象被一个不再使用的变量引用&#xff0c;它将不会被垃圾回收。事件订阅者未取消&#xff1a;如果订阅了一个事件但没有在对象不再需要时取消订阅&…

TDengine Restful 接口API

简介 为支持各种不同类型平台的开发&#xff0c;TDengine 提供符合 RESTful 设计标准的 API&#xff0c;即 REST API。为最大程度降低学习成本&#xff0c;不同于其他数据库 REST API 的设计方法&#xff0c;TDengine 直接通过 HTTP POST 请求 BODY 中包含的 SQL 语句来操作数…

【Contiki】Contiki process概述

00. 目录 文章目录 00. 目录01. 进程类型02. 进程结构03. 事件04. 进程调度函数05. 程序实例06. process实现07. 附录 01. 进程类型 进程类型主要有**协同式&#xff08;cooperative&#xff09;和抢占式&#xff08;preemptive&#xff09;**两种。 协同式进程&#xff0c;要…

哪种电脑更稳定?Mac?Windows?还是云电脑? 实测解密

随着科技的发展进步&#xff0c;电脑已成为当下各类群体的必备产品之一&#xff0c;它的妙用有很多&#xff0c;无论是学生党、打工人还是已经退休的人群或都离不开它的存在。然而&#xff0c;电脑虽好却也差异很大、不同品牌、不同系统、不同配置、不同价位的统统都会有区别。…

华为openEuler操作系统全解析:起源、特性与生态对比

华为openEuler操作系统全解析&#xff1a;起源、特性与生态对比 一、起源与发展历程 openEuler&#xff08;欧拉操作系统&#xff09;是华为于2019年开源的Linux发行版&#xff0c;其前身为华为内部研发的服务器操作系统EulerOS。EulerOS自2010年起逐步发展&#xff0c;支持华…

第 7 期:DDPM 采样提速方案:从 DDPM 到 DDIM

本期关键词:采样加速、DDIM 推导、可控性提升、伪逆过程、代码实战 前情回顾:DDPM 的采样瓶颈 在前几期中,我们构建了一个完整的 DDPM 生成流程。但是你可能已经发现: 生成一张图像太慢了!!! 原因是: DDPM 要在 T 个时间步中一步步地去噪,从 x_T → x_0。而通常 T 至…

chrome中的copy xpath 与copy full xpath的区别

学过测试或者爬虫的&#xff0c;都感觉获取网页元素&#xff0c;使用xpath最方便 但其中有一些细节可能会使你摸不清头脑 比如有时候copy xpath会定位不准确&#xff0c;而使用copy full xpath就可以定位 1、copy xpath&#xff08;相对路径定位&#xff09; 优点&#xff…

学习海康VisionMaster之中线查找

一&#xff1a;进一步学习了 今天学习下VisionMaster中的中线查找&#xff0c;这个就是字面意思&#xff0c;输入两条直线&#xff0c;输出两条直线的中线 二&#xff1a;开始学习 1&#xff1a;什么是中线查找&#xff1f;今天这个比较简单&#xff0c;其实这个模块算是一个几…