APP开发_ js 控制手机是否显示状态栏

server/2024/11/15 5:46:26/

1 Android 控制手机显示或隐藏状态栏的方法

1.1 使用 View 的 setSystemUiVisibility 方法

这个方法允许设置系统 UI 的可见性,包括状态栏。你可以通过组合不同的标志来实现不同的效果。

示例代码:

@Override  
protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  // 获取DecorView,这是Activity的最顶层视图  View decorView = getWindow().getDecorView();  // 设置系统UI的可见性  int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN; // 隐藏状态栏  decorView.setSystemUiVisibility(uiOptions);  
}

常用的标志:

  • View.SYSTEM_UI_FLAG_FULLSCREEN: 隐藏状态栏。
  • View.SYSTEM_UI_FLAG_HIDE_NAVIGATION: 隐藏导航栏。
  • View.SYSTEM_UI_FLAG_IMMERSIVE: 沉浸式模式,允许用户通过滑动屏幕边缘来显示系统栏。
  • View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY: 类似于 IMMERSIVE,但系统栏在显示后会短暂延迟隐藏。

1.2 使用 Window 的 addFlags 和 clearFlags 方法

可以通过Window对象来添加或清除特定的窗口标志,从而控制状态栏的显示。

示例代码:

@Override  
protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  // 获取Window对象  Window window = getWindow();  // 隐藏状态栏  window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);  // 如果需要再次显示状态栏  // window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);  
}

1.3 处理状态栏的重新显示

在某些情况下,如用户滑动屏幕或收到通知,状态栏可能会重新显示。为了确保用户体验的连贯性,你可能需要在onWindowFocusChanged方法中监听窗口焦点的变化,并相应地调整系统UI的可见性。

示例代码:

@Override  
public void onWindowFocusChanged(boolean hasFocus) {  super.onWindowFocusChanged(hasFocus);  if (hasFocus) {  View decorView = getWindow().getDecorView();  decorView.setSystemUiVisibility(  View.SYSTEM_UI_FLAG_LAYOUT_STABLE  | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION  | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN  | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // 隐藏导航栏  | View.SYSTEM_UI_FLAG_FULLSCREEN // 隐藏状态栏  | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); // 沉浸式模式  }  
}

1.4 使用 WindowInsetsController 类

在 Android 开发中,随着版本的更新,API 也提供了更加灵活和强大的方法来控制状态栏的显示或隐藏。从 Android R(API级别30)开始,引入了 WindowInsetsController 类,它提供了一种更直观和强大的方式来控制窗口插入(包括状态栏和导航栏)的可见性。

使用 WindowInsetsController,可以实现更精细的控制,比如平滑地隐藏或显示状态栏,以及处理用户与这些系统 UI 元素的交互。

(1)获取 WindowInsetsController 实例

首先,需要在 Activity 或 Fragment 中获取 WindowInsetsController 的实例。这通常通过 Window 对象来实现。

WindowInsetsController controller;  
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {  controller = getWindow().getInsetsController();  
}

确保检查 API 级别,因为 WindowInsetsController 只在 API 级别 30 及更高版本中可用。

(2)控制状态栏的显示或隐藏
一旦有了 WindowInsetsController 的实例,就可以使用它来控制状态栏的显示或隐藏了。

  • 隐藏状态栏
if (controller != null) {  controller.hide(WindowInsets.Type.statusBars());  
}
  • 显示状态栏
if (controller != null) {  controller.show(WindowInsets.Type.statusBars());  
}

(3)设置状态栏的行为和外观

除了基本的显示和隐藏,WindowInsetsController 还允许设置状态栏的行为和外观。

  • 设置状态栏的外观

可以使用 setAppearanceLightStatusBars 和 setAppearanceDarkStatusBars 方法来改变状态栏的颜色模式。

if (controller != null) {  // 设置状态栏为亮色模式  controller.setAppearanceLightStatusBars(true);  // 或者设置为暗色模式  controller.setAppearanceDarkStatusBars(true);  
}
  • 设置状态栏的隐藏模式

还可以设置状态栏隐藏时的行为模式,比如是否允许用户通过滑动来显示状态栏。

if (controller != null) {  // 设置沉浸式模式,允许用户通过滑动来显示状态栏  controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);  
}

(4)监听状态栏的变化

可以添加监听器来监听状态栏的变化,以便在状态栏显示或隐藏时执行特定的操作。

if (controller != null) {  controller.addOnControlVisibilityChangeListener(new View.OnControlVisibilityChangeListener() {  @Override  public void onControlVisibilityChange(ControlVisibility controlVisibility) {  if (controlVisibility.statusBars == ControlVisibility.VISIBLE) {  // 状态栏变为可见  } else {  // 状态栏变为隐藏  }  }  });  
}

2 提供 js 调用 Android 方法

重点注意:需要通过异步的方式调用显示或隐藏状态栏的方法,否则 JS 会报错,并且设置失败。

(1)创建 JavaScriptInterface 类

首先,需要创建一个 Java 类,实现 WebView.JavascriptInterface 接口。这个类将作为 JavaScript 和 Android 原生代码之间的桥梁。

import android.content.Context;
import android.webkit.JavascriptInterface;
import android.widget.Toast;public class WebAppInterface {Context mContext;/** Instantiate the interface and set the context */WebAppInterface(Context c) {mContext = c;}// 隐藏系统栏@JavascriptInterfacepublic void hideSystemUI() {executorService = Executors.newSingleThreadExecutor();Future<String> future = executorService.submit(new Callable<String>() {@Overridepublic String call() throws Exception {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {WindowInsetsController controller = ((Activity) mContext).getWindow().getInsetsController();if (controller != null) {// 隐藏状态栏controller.hide(WindowInsets.Type.statusBars());// 如果你想在用户交互后自动显示系统栏,可以使用SYSTEM_BARS_BEHAVIOR_SHOW_TRANSIENT_BARS或SYSTEM_BARS_BEHAVIOR_SHOW_BARS_BY_SWIPE// controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);}}return "";}});try {// 当需要结果时,阻塞等待Future完成String result = future.get();System.out.println("异步操作结果: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();} finally {executorService.shutdown(); // 关闭ExecutorService}}// 显示系统栏@JavascriptInterfacepublic void showSystemUI() {executorService = Executors.newSingleThreadExecutor();Future<String> future = executorService.submit(new Callable<String>() {@Overridepublic String call() throws Exception {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {WindowInsetsController controller = ((Activity) mContext).getWindow().getInsetsController();if (controller != null) {// 显示状态栏controller.show(WindowInsets.Type.statusBars());}}return "";}});try {// 当需要结果时,阻塞等待Future完成String result = future.get();System.out.println("异步操作结果: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();} finally {executorService.shutdown(); // 关闭ExecutorService}}
}

注意,@JavascriptInterface 注解是必须的,该注解允许 Android 识别哪些方法可以被 JavaScript 调用。

(2)在 WebView 中启用 JavaScript 并添加接口

然后,在 Activity 或 Fragment 中,需要初始化 WebView,启用 JavaScript,并将创建的 JavaScriptInterface 实例添加到 WebView 中。

import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private WebView webView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);webView = findViewById(R.id.webview);webView.getSettings().setJavaScriptEnabled(true);webView.addJavascriptInterface(new WebAppInterface(this), "Android");webView.setWebViewClient(new WebViewClient() {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {view.loadUrl(url);return true;}});// 加载一个HTML页面,或者直接使用webView.loadDataWithBaseURL()加载包含JavaScript的字符串webView.loadUrl("file:///android_asset/my_page.html");}
}

这里,addJavascriptInterface 方法的第一个参数是 JavaScriptInterface 的实例,第二个参数是 JavaScript 中用来访问这个接口的对象名(这里使用了 “Android”)。

(3)在 HTML 中调用 Android 设置显示或隐藏状态栏的方法

在 HTML 页面中,即可以使用 JavaScript 来调用 Android 方法。

<!DOCTYPE html>
<html>
<head><title>WebView JavaScript Interface Example</title><script type="text/javascript">javascript">function hideSystemUI() {// 调用Android方法Android.hideSystemUI();}function showSystemUI() {// 调用Android方法Android.showSystemUI();}</script>
</head>
<body><h1>WebView JavaScript Interface Example</h1><button onclick="javascript language-javascript">hideSystemUI()">隐藏状态栏</button><button onclick="javascript language-javascript">showSystemUI()">显示状态栏</button>
</body>
</html>

http://www.ppmy.cn/server/18278.html

相关文章

<c++基础(6)>宏定义与函数的区别

最近需要使用openvino封装动态库&#xff0c;其中存在一个问题是openvino和windows.h之间的冲突&#xff0c;其主要是minwaindef.h中的宏定义引起的。所以好奇为什么使用宏定义处理函数过程。 //minwaindef.h中关于min、max的宏定义 #ifndef max #define max(a,b) …

ELK 日志分析系统(二)

一、ELK Kibana 部署 1.1 安装Kibana软件包 #上传软件包 kibana-5.5.1-x86_64.rpm 到/opt目录 cd /opt rpm -ivh kibana-5.5.1-x86_64.rpm 1.2 设置 Kibana 的主配置文件 vim /etc/kibana/kibana.yml --2--取消注释&#xff0c;Kiabana 服务的默认监听端口为5601 server.po…

设计模式之命令模式

一、详细介绍 命令模式是一种行为型设计模式&#xff0c;它将“请求”封装为一个对象&#xff0c;使得使用请求、参数化请求、队列请求、撤销请求、日志请求等多种请求变得简单。命令模式通过将“行为请求者”与“行为实现者”解耦&#xff0c;使得请求的发送者和接收者完全分离…

vue的v-model、v-if、v-for用react语法实现

在React中&#xff0c;没有直接对应于Vue中的v-model、v-if和v-for的指令&#xff0c;但你可以使用React的特性和组件来实现类似的功能。 1. v-model 在Vue中&#xff0c;v-model用于在表单元素和组件之间创建双向数据绑定。在React中&#xff0c;你可以使用受控组件&#xf…

【bug】vuxUI组件popup弹出框在IOS中遮罩层会遮住页面

可以增加自定义方法v-transfer-dom <div v-transfer-dom"true"><Popup v-model"showPopup"><PopupHeader :title"policyloan.docJson.title" /><div class"noticeText"><p v-for"(item, index) in po…

人脸识别开发项目汇总

1.基于FaceX-Zoo实现的人脸识别系统-CSDN博客 2.人脸识别&#xff1a;京东开源FaceX-Zoo&#xff1a;PyTorch工具箱 - 知乎 (zhihu.com) 3.人头识别-人群中准确快速的检测头部算法_在输入图像中检测人像头部的方法-CSDN博客 4.Github开源人脸识别项目face_recognition - 知乎…

SpringBoot:SpringMVC(下)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、RequestBody补充二、PathVariable三.RequestPart:四.ResponseBody五.CookieValue&#xff0c;SessionAttribute&#xff0c;RequestHeader 前言 提示&…

贪心(贪婪)算法

主要思想 贪心算法的思想主要可以概括为“总是做出当前看起来最优的选择”&#xff0c;也就是不从整体上进行考虑&#xff0c;所得到的答案是某种意义上的局部最优解&#xff0c;不一定是整体最优解。 贪心算法没有固定算法框架&#xff0c;算法设计的关键是贪心策略的选择。…