Android 15 应用适配默认全屏的行为变更(Android V的新特性)

简介

Android V 上默认会使用全面屏兼容方式,影响应用显示,导致应用内跟导航标题重合,无法点击上移的内容。

默认情况下,如果应用以 Android 15(API 级别 35)为目标平台,在搭载 Android 15 的设备上,应用默认采用全屏。

解决方案

先说适配方案,后面有官方文档的介绍说明变更内容、应用自查方法和配置建议。

方法:实现无边框应用。

如何检查应用尚未实现无边框

如果您的应用还没有全面屏,那么您很可能会受到影响。除了针对已经采用无边框的应用的情况之外,您还应考虑以下事项:

  • 如果您的应用在 Compose 中使用 Material 3 组件 (androidx.compose.material3)(例如 TopAppBarBottomAppBar 和 NavigationBar),这些组件可能不会受到影响,因为它们会自动处理边衬区。
  • 如果您的应用在 Compose 中使用 Material 2 组件 (androidx.compose.material),这些组件不会自动处理边衬区。不过,您可以访问边衬区,并手动应用边衬区。在 androidx.compose.material 1.6.0 及更高版本中,使用 windowInsets 参数为 BottomAppBar、TopAppBar、BottomNavigation 和 NavigationRail 手动应用边衬区。同样,对 Scaffold 使用 contentWindowInsets 参数。
  • 如果您的应用使用视图和 Material 组件 (com.google.android.material),则大多数基于视图的 Material 组件(例如 BottomNavigationViewBottomAppBarNavigationRailView 或 NavigationView)均可处理边衬区,无需执行额外的操作。不过,如果使用 AppBarLayout,则需要添加 android:fitsSystemWindows="true"
  • 对于自定义可组合项,请手动将边衬区作为内边距应用。如果您的内容在 Scaffold 内,您可以使用 Scaffold 内边距值使用边衬区。否则,请使用某个 WindowInsets 应用内边距。
  • 如果您的应用使用视图和 BottomSheetSideSheet 或自定义容器,请使用 ViewCompat.setOnApplyWindowInsetsListener 应用内边距。对于 RecyclerView,请使用此监听器应用内边距,并添加 clipToPadding="false"

(一)针对传统的Java传统视图参考方案(无Compose使用)

【Java】创建界面时,设置属性 fitsSystemWindows属性为 true

如果做成插件化,没有使用Activity布局可配置,如PreferenceScreen中没有android:fitsSystemWindows="true"配置,且设置activitybase.xml线性布局此属性也无法解决,可选择在onCreateView生命周期中渲染界面。

public class MainPref extends PreferenceFragmentBaseimplements Preference.OnPreferenceChangeListener {public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View rootView = super.onCreateView(inflater, container, savedInstanceState);Log.d(TAG, "onCreateView: rootView = "+ rootView + ", setFitsSystemWindows=true.");if (rootView != null) {rootView.setFitsSystemWindows(true);}return rootView;}

Note:在一个包含 Fragment 的 Activity 中,onCreate()方法会先被调用,然后再调用 Fragment 的onCreateView()方法。 

(二)针对Compose的方案:

1、在build.gradle 添加编译依赖

dependencies {implementation "androidx.core:core-ktx:1.6.0" // 当前释放最新应该是1.6.0,可以需修改成以后更新版本implementation "androidx.appcompat:appcompat:1.3.1"implementation "androidx.constraintlayout:constraintlayout:2.0.4"
}

2、【XML】修改manifest配置布局 fitsSystemWindows属性为 true

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"android:id="@+id/main_layout"tools:context=".MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

3、【Java】修改Activity创建逻辑

默认情况下,每个 ComposeView 都会使用 WindowInsetsCompat 级别使用的所有边衬区。如需更改此默认行为,请将 ComposeView.consumeWindowInsets 设置为 false

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//拿到自定义id的布局进行操作ConstraintLayout mainLayout = findViewById(R.id.main_layout);ViewCompat.setOnApplyWindowInsetsListener(mainLayout, (v, windowInsets) -> {WindowInsetsCompat insetsCompat = ViewCompat.getRootWindowInsets(v);if (insetsCompat != null) {Insets insets = insetsCompat.getInsets(WindowInsetsCompat.Type.systemBars());Log.d(TAG, "left = " + insets.left + ", top = " + insets.top + ", right = " + insets.right + ", bottom = " + insets.bottom);v.setPadding(insets.left, insets.top, insets.right, insets.bottom);} else {Log.d(TAG, "insetsCompat is null");}// 获取 WindowInsetsControllerCompat 实例WindowInsetsControllerCompat windowInsetsController = ViewCompat.getWindowInsetsController(v);if (windowInsetsController != null) {// 设置状态栏图标和文字为深色windowInsetsController.setAppearanceLightStatusBars(true);}// Return CONSUMED if you don't want want the window insets to keep passing// down to descendant views.return WindowInsetsCompat.CONSUMED;});
}

官方文档

1、变更说明:行为变更:以 Android 15 或更高版本为目标平台的应用  |  Android Developers

2、全面屏&无边框应用自检步骤:检查应用是否已采用全屏的检查步骤  |  Android Developers

3、配置建议:稳定配置  |  Android Developers (google.cn)

UI案例

1、在Android 14的设备上,如果应用没有升级API版本则不会出现Android 15 SDK全面屏导致的负面影响:

以 Android 14 为目标平台且在 Android 15 设备上非全屏的应用。
以 Android 14 为目标平台且在 Android 15 设备上非全屏的应用

全屏强制应用

2、当API和系统都是Android 15时,会受到全面屏负面影响,导致top Bar和导航栏异常重合问题。

由于 Android 15 全屏强制措施,现在许多元素被状态栏、“三按钮”导航栏或刘海屏隐藏。隐藏界面包括 Material 2 顶部应用栏、悬浮操作按钮和列表项。

以 Android 15(API 级别 35)为目标平台且在 Android 15 设备上为全屏的应用
以 Android 15(API 级别 35)为目标平台且在 Android 15 设备上为全屏的应用

无边框应用

3、在 Android 15 设备上采用无边框应用,并应用边衬区以便不隐藏界面。

以 Android 15(API 级别 35)为目标平台的应用,在 Android 15 设备上采用无边框应用
以 Android 15(API 级别 35)为目标平台的应用,在 Android 15 设备上采用无边框应用

如需了解应用边衬区的其他注意事项,请参阅无边框视图和无边框 Compose 指南。

配置说明

如果您的应用以 Android 15 或更高版本为目标平台,Configuration 将不再排除系统栏。如果您在 Configuration 类中使用屏幕尺寸计算布局,则应根据需要将其替换为合适的 ViewGroupWindowInsets 或 WindowMetricsCalculator 等更好的替代方案。

从 API 1 开始,Configuration 一直可用。它通常从 Activity.onConfigurationChanged 获取。它可提供窗口密度、方向和大小等信息。从 Configuration 返回的窗口大小的一个重要特征是它之前排除了系统栏。

配置大小通常用于资源选择(如 /res/layout-h500dp),这仍然是一个有效的用例。不过,我们一直不建议将其用于布局计算。如果这样做,您应该立即离开。您应该根据自己的使用场景,将 Configuration 替换为更合适的代码。

如果您使用其计算布局,请使用适当的 ViewGroup,例如 CoordinatorLayout 或 ConstraintLayout。如果您使用它来确定系统导航栏的高度,请使用 WindowInsets。如果您想知道应用窗口的当前大小,请使用 computeCurrentWindowMetrics

以下列表介绍了受此更改影响的字段:

  • Configuration.screenWidthDp 和 screenHeightDp 尺寸不再排除系统栏。
  • Configuration.smallestScreenWidthDp 会受到 screenWidthDp 和 screenHeightDp 更改的间接影响。
  • 在近方形设备上,对 screenWidthDp 和 screenHeightDp 的更改会间接影响 Configuration.orientation。
  • Display.getSize(Point) 会受到 Configuration 中变更的间接影响。从 API 级别 30 开始,此 API 已被废弃。
  • 从 API 级别 33 开始,Display.getMetrics() 就一直以这种方式运行。

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

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

相关文章

【SQLite3】常用API

SQLite3常用API 数据库的打开和关闭 数据库的打开&#xff08;sqlite3_open函数&#xff09; sqlite3_open() 函数用于打开一个 SQLite 数据库文件的函数&#xff0c;函数原型如下&#xff1a; int sqlite3_open(const char *filename, /* 数据库文件的文件名&#xff0c…

.net6+ 在单文件应用程序中获取程序集位置

一般来说,获取执行程序集的位置&#xff0c;您可以调用: var executableDirectory System.Reflection.Assembly.GetExecutingAssembly().Location;如果发布为单个文件, 会提示如下警告 warning IL3000: System.Reflection.Assembly.Location always returns an empty string…

解析Java中1000个常用类:EnumMap类,你学会了吗?

在线工具站 推荐一个程序员在线工具站&#xff1a;程序员常用工具&#xff08;http://cxytools.com&#xff09;&#xff0c;有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具&#xff0c;效率加倍嘎嘎好用。 程序员资料站 推荐一个程序员编程资料站&#xff1a;…

python破解字母已知但大小写未知密码

python穷举已知字符串中某个或多个字符为大写的所有情况 可以使用递归函数来实现这个功能。以下是一个示例代码&#xff1a; def generate_uppercase_combinations(s, index0, current):if index len(s):print(current)returngenerate_uppercase_combinations(s, index 1, …

图神经网络dgl和torch-geometric安装

文章目录 搭建环境dgl的安装torch-geometric安装 在跑论文代码过程中&#xff0c;许多小伙伴们可能会遇到一些和我一样的问题&#xff0c;就是文章所需要的一些库的版本比较老&#xff0c;而新版的环境跑代码会报错&#xff0c;这就需要我们手动的下载whl格式的文件来安装相应的…

数字信号处理及MATLAB仿真(3)——量化的其他概念

上回书说到AD转换的两个步骤——量化与采样两个步骤。现在更加深入的去了解以下对应的概念。学无止境&#xff0c;要不断地努力才有好的收获。万丈高楼平地起&#xff0c;唯有打好基础&#xff0c;才能踏实前行。 不说了&#xff0c;今天咱们继续说说这两个步骤&#xff0c;首先…

cloudflare tunnels tcp

这里是官网的说明Cloudflare Tunnel Cloudflare Zero Trust docs 根据实际情况安装环境 tunnels除了http,https协议是直接暴露公网&#xff0c;tcp是类似ssh端口转发。 在需要内网穿透的局域网找一条机子部署代理 我这边是window cloudflared tunnel login #生成一个身份校…

计算机网络 5.4中继器 5.5集线器

第四节 中继器 一、认识中继器 1.作用&#xff1a;对信号整形、放大&#xff0c;使之传播更远的距离。 2.特点&#xff1a; ①由中继器连接起来的两端必须采用相同介质访问控制协议。 ②理论上中继器的使用是无限的&#xff0c;但实际只能在规定的范围内有效工作&#xff0…

windows上传app store的构建版本简单方法

我们在上传app store上架&#xff0c;或上传到testflight进行ios的app测试的时候&#xff0c;需要mac下的上传工具上传ipa文件到app store的构建版本上。 然而windows电脑这些工具是无法安装的。 因此&#xff0c;假如在windows上开发hbuilderx或uniapp的应用&#xff0c;可以…

Mobile ALOHA: 你需不需要一个能做家务的具身智能机器人

相信做机器人的朋友最近一段时间一定被斯坦福华人团队这个Mobile ALOHA的工作深深所震撼&#xff0c;这个工作研究了一个能做饭&#xff0c;收拾衣服&#xff0c;打扫卫生的服务机器人&#xff0c;完成了传统机器人所不能完成的诸多任务&#xff0c;向大家展示了服务机器人的美…

一文全解Nginx

一文全解Nginx 一文全解 Nginx 1. 技术介绍 Nginx&#xff08;发音为"engine-x"&#xff09;是一个高性能的开源 Web 服务器软件&#xff0c;同时也可以用作反向代理、负载均衡器和 HTTP 缓存。它最初由俄罗斯的 Igor Sysoev 开发&#xff0c;并于 2004 年首次公开…

在Qt中使用C++编程与传统C++编程的区别

引言 C作为一种强大的编程语言&#xff0c;被广泛应用于系统编程、游戏开发、嵌入式系统等领域。而Qt作为一个跨平台的应用开发框架&#xff0c;通过其丰富的功能库和高效的开发工具&#xff0c;使得C开发变得更加高效和便捷。本文将深入探讨在Qt中使用C编程与传统C编程的区别…

el-date-picker 设置默认值为当前日期

this.listQuery.Date new Date().toISOString().substr(0, 10); <el-date-picker v-model"listQuery.Date" format"yyyy-MM-dd" value-format"yyyy-MM-dd" type"date" placeholder"选择日期" change"getList()&qu…

【MySQL】4.MySQL 的数据类型

MySQL 的数据类型 一.数据类型分类在这里插入图片描述二.注意点1.char VS varchar2.datetime VS timestamp3.enum 和 set 的使用方法 一.数据类型分类 二.注意点 1.char VS varchar char 的意义是直接开辟固定大小的空间&#xff0c;浪费磁盘空间&#xff0c;但是效率高varcha…

WEB05Web开发HTMLCSS

Web前端开发 什么是 Web &#xff1f; Web&#xff1a;全球广域网&#xff0c;也称为万维网(www World Wide Web)&#xff0c;能够通过浏览器访问的网站。 Web 网站的工作流程 W3C 万维网联盟&#xff08; World Wide Web Consortium &#xff09;&#xff0c;创建于1994年1…

ESP32-C3模组上跑通AES-GCM(1)

本文内容参考: mbedtls学习笔记 AES GCM_aes128 gcm的aad是什么-CSDN博客 https://www.cnblogs.com/testlearn/p/16547583.html 对称加密和非对称加密,一文讲解明白!-CSDN博客 深入理解高级加密标准(Advanced Encryption Standard)_aes在线加密-CSDN博客 特此致谢! …

OpenEarthMap:全球高分辨率土地覆盖制图的基准数据集(开源来下载!!!)

OpenEarthMap由220万段5000张航拍和卫星图像组成&#xff0c;覆盖6大洲44个国家97个地区&#xff0c;在0.25-0.5m的地面采样距离上人工标注8类土地覆盖标签。我们提供8类标注:裸地、牧场、已开发空间、道路、树木、水、农业用地和建筑。类选择与现有的具有亚米GSD的产品和基准数…

std::unordered_map和std::map在性能上有何不同

std::unordered_map和std::map在性能上的不同主要体现在以下几个方面&#xff1a; 1. 底层数据结构 std::unordered_map&#xff1a;基于哈希表实现&#xff0c;通过哈希函数计算元素的存储位置。哈希表能够直接通过哈希值快速定位到元素的位置&#xff0c;从而实现高效的查找…

30、PHP 实现 左旋转字符串、翻转单词顺序列

题目&#xff1a; PHP 实现 左旋转字符串 描述&#xff1a; 汇编语言中有一种移位指令叫做循环左移&#xff08;ROL&#xff09;&#xff0c;现在有个简单的任务&#xff0c; 就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S&#xff0c;请你把其循环左移K位后的…

电源纹波相关

什么是纹波&#xff1f;什么是噪声&#xff1f; 这种叠加在直流稳定量上的交流分量就称为纹波。 纹波的危害 电源纹波能影响设备性能和稳定性 纹波会导致电器上产生谐波&#xff0c;降低电源的使用效率&#xff1b; 高频电源纹波可能会产生浪涌电压或电流&#xff0c;影响设…