Android状态栏适配问题

embedded/2024/10/21 6:46:20/

Android状态栏适配是一个老生常谈的问题,那么我又拿出来讲了,因为这个东西确实太重要了,基本上每个项目都用得到。状态栏总共有几种形态。第一,让状态栏颜色跟应用主色调一致,布局内容不占有状态栏的位置。第二,让布局内容的顶部成为状态栏的一部分,状态栏透明。第三,有DrawerLayout的情况,侧边栏滑出来,一半侧边栏的顶部界面,一半内容的顶部界面,且不透明。

让状态栏颜色跟应用主色调一致,布局内容不占有状态栏的位置

设置非全屏的状态栏颜色

/*** 设置不全屏内容的状态栏颜色。** @param activity       需要设置的activity* @param statusBarColor 状态栏颜色值* @param statusBarAlpha 状态栏透明度*/
public static void setStatusBar(Activity activity, @ColorInt int statusBarColor, @IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// >= 6.0 支持根据状态栏颜色定制浅色和深色的文字和图标activity.getWindow().setStatusBarColor(statusBarColor);int option;if (isDarkColor(statusBarColor)) {// 深色状态栏,则让状态栏文字和图标变白option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;} else {// 浅色状态栏,则让状态栏文字和图标变黑option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_VISIBLE;}activity.getWindow().getDecorView().setSystemUiVisibility(option);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {// 5.xactivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().setStatusBarColor(calculateColor(statusBarColor, statusBarAlpha));} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4 自己创建一个色块加到DecorViewactivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();View doraStatusBarView = decorView.findViewById(DORA_STATUS_BAR_VIEW_ID);if (doraStatusBarView != null) {if (doraStatusBarView.getVisibility() == View.GONE) {doraStatusBarView.setVisibility(View.VISIBLE);}doraStatusBarView.setBackgroundColor(calculateColor(statusBarColor, statusBarAlpha));} else {decorView.addView(createStatusBarView(activity, statusBarColor, statusBarAlpha));}setFitsSystemWindow(activity);} else {// < 4.4 不可定制,黑色状态栏,无解}
}

检测状态栏的颜色,以确定用深色还是浅色的文字和图标

/*** 状态栏是否是深色。** @param color 状态栏颜色值*/
public static boolean isDarkColor(@ColorInt int color) {int gray = (int) (Color.red(color) * 0.299 + Color.green(color) * 0.587 + Color.blue(color) * 0.114);return gray >= 192;
}

自己创建一个和状态栏一样高度的色块。

/*** 生成一个和状态栏大小相同的矩形条。** @param activity 需要设置的activity* @param color    状态栏颜色值* @param alpha    状态栏透明度* @return 状态栏矩形条*/
private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {// 绘制一个和状态栏一样高的矩形View statusBarView = new View(activity);LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));statusBarView.setLayoutParams(params);statusBarView.setBackgroundColor(calculateColor(color, alpha));statusBarView.setId(DORA_STATUS_BAR_VIEW_ID);return statusBarView;
}

根布局设置fitsSystemWindow

private static void setFitsSystemWindow(Activity activity) {ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);for (int i = 0, count = parent.getChildCount(); i < count; i++) {View childView = parent.getChildAt(i);if (childView instanceof ViewGroup) {childView.setFitsSystemWindows(true);((ViewGroup) childView).setClipToPadding(true);}}
}

获取状态栏的高度

private static int getStatusBarHeight(Context context) {int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");return context.getResources().getDimensionPixelSize(resourceId);
}

计算带透明度后的颜色

private static int calculateColor(@ColorInt int color, int alpha) {if (alpha == 0) {return color;}float a = 1 - alpha / 255f;int red = color >> 16 & 0xff;int green = color >> 8 & 0xff;int blue = color & 0xff;red = (int) (red * a + 0.5);green = (int) (green * a + 0.5);blue = (int) (blue * a + 0.5);return 0xff << 24 | red << 16 | green << 8 | blue;
}

让布局内容的顶部成为状态栏的一部分,状态栏透明

public static void setFullScreenStatusBar(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().setStatusBarColor(Color.TRANSPARENT);} else {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

DrawerLayout设置状态栏颜色

设置DrawerLayout的状态栏一半的颜色

public static void setStatusBar(Activity activity, DrawerLayout drawerLayout, @ColorInt int statusBarColor,@IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().setStatusBarColor(Color.TRANSPARENT);} else {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);View doraStatusBarView = contentLayout.findViewById(DORA_STATUS_BAR_VIEW_ID);if (doraStatusBarView != null) {if (doraStatusBarView.getVisibility() == View.GONE) {doraStatusBarView.setVisibility(View.VISIBLE);}doraStatusBarView.setBackgroundColor(statusBarColor);} else {contentLayout.addView(createStatusBarView(activity, statusBarColor), 0);}if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {contentLayout.getChildAt(1).setPadding(contentLayout.getPaddingLeft(), getStatusBarHeight(activity) + contentLayout.getPaddingTop(),contentLayout.getPaddingRight(), contentLayout.getPaddingBottom());}setFitsSystemWindow(drawerLayout, contentLayout);addStatusBarView(activity, statusBarAlpha);
}

设置fitsSystemWindow

private static void setFitsSystemWindow(DrawerLayout drawerLayout, ViewGroup drawerLayoutContentLayout) {ViewGroup drawer = (ViewGroup) drawerLayout.getChildAt(1);drawerLayout.setFitsSystemWindows(false);drawerLayoutContentLayout.setFitsSystemWindows(false);drawerLayoutContentLayout.setClipToPadding(true);drawer.setFitsSystemWindows(false);
}

添加状态栏View

/*** 添加半透明矩形条。** @param activity       需要设置的 activity* @param statusBarAlpha 状态栏透明度*/
private static void addStatusBarView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);View doraStatusBarView = contentView.findViewById(DORA_STATUS_BAR_VIEW_ID);if (doraStatusBarView != null) {if (doraStatusBarView.getVisibility() == View.GONE) {doraStatusBarView.setVisibility(View.VISIBLE);}doraStatusBarView.setBackgroundColor(Color.argb(statusBarAlpha, 0, 0, 0));} else {contentView.addView(createTranslucentStatusBarView(activity, statusBarAlpha));}
}

http://www.ppmy.cn/embedded/46759.html

相关文章

Scalable Membership Inference Attacks via Quantile Regression

我们使用以下六个分类标准: 动机: 隐私问题:许多研究背后的主要动机是对机器学习模型相关的隐私风险日益增长的担忧。例如,Shokri等人(2017)和Carlini等人(2022)专注于开发和改进成员推理攻击,以评估模型对隐私泄露的脆弱性。模型理解:一些研究深入了解机器学习模型的固有…

php: centos+apache 启动php项目

指导文件 &#xff1a;PHP: Apache 2.x on Unix systems - Manual 下载路径 &#xff1a;Index of /httpd configure: error: APR not found. 解决方案&#xff1a; APR&#xff08;Apache Portable Runtime&#xff09;库。APR是Apache HTTP服务器的可移植运行时环境&…

2024-06-05-记一次cnvd渗透

前言&#xff1a;挖src挖郁闷了&#xff0c;闲来无事选择挖一个cnvd来练练手&#xff0c;本次的漏洞都没啥难度&#xff0c;企查查资产过了5000万 说一下cnvd证书的下放标准 对于中危及中危以上通用型漏洞&#xff08;CVSS2.0基准评分超过4.0分&#xff09;&#xff0c;以及涉…

举例说明async 和 await 在 .NET Core 中的基本使用

异步编程在 .NET Core 中变得越来越重要&#xff0c;async 和 await 关键字是实现异步编程的基础。下面我们将通过一个示例来说明如何使用它们。 示例代码 下面是一个简单的示例&#xff0c;演示了如何使用 async 和 await 来执行异步操作&#xff1a; using System; using …

Java扩展机制:SPI与Spring.factories详解

一、SPI SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。 整体机制图如下: Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制。 系统设计的各个抽象,往往有很多不…

QT之可拖动布局研究

1. 背景 最开始只用到了最基本的水平布局 、垂直布局。它的好处就是窗口整体缩放后&#xff0c;控件也自动等比例缩放。 但是比如水平布局之中的控件宽度比例、垂直布局之中的控件高度比例都是固定的。 平时也不怎么开发界面&#xff0c;最近有个需求&#xff0c;想界面上的…

探索营销系统业务架构的设计与应用

随着市场竞争的日益激烈和消费者需求的不断变化&#xff0c;营销系统作为企业营销管理的重要组成部分&#xff0c;扮演着至关重要的角色。本文将深入探讨营销系统业务架构的设计与应用&#xff0c;从客户关系管理、营销活动管理、数据分析和智能化服务等方面进行全面解析&#…

【MMU】——简介

文章目录 MMU 简介MMU 作用地址翻译页式内存管理段式内存管理段页式内存管理内存保护存取数据模型MMU 简介 Memory Manage Unit 存储器管理单元是一种硬件模块,用于在 CPU 和内存之间实现虚拟内存管理。 其主要功能是将虚拟地址转换为物理地址,同时提供访问权限的控制和缓存…