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 PreferenceFragmentBase
        implements 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.mfbz.cn/a/769669.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【网络安全的神秘世界】SQL注入(下)

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 3.7 二次注入 不好挖这个漏洞&#xff0c;需要搞懂业务逻辑关系 二次注入通常是指在存入数据库时做了过滤&#xff0c;但是取…

vue中自定义设置多语言,并且运行js脚本自动生成多语言文件

在项目中需要进行多个国家语言的切换时&#xff0c;可以用到下面方法其中一个 一、自定义设置多语言 方法一: 可以自己编写一个设置多语言文件 在项目新建js文件&#xff0c;命名为&#xff1a;language.js&#xff0c;代码如下 // language.js 文档 let languagePage {CN…

Rocky Linux yum/dnf repo/mirrors 国内镜像列表及更换方法

Rocky Linux yum/dnf repo/mirrors 国内镜像列表及更换方法 Rocky Linux Mirrors 请访问原文链接&#xff1a;https://sysin.org/blog/rocky-linux-mirrors/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 高校镜像推荐 mirr…

聚观早报 | 微信升级视频功能;一加Ace 3 Pro开启销售

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 7月4日消息 微信升级视频功能 一加Ace 3 Pro开启销售 享界S9将亮相门店 澎湃OS出行助手将陆续升级 特斯拉公布二…

DDOS攻击不懂?看完让你秒懂!

什么是DDOS攻击&#xff1f; DDoS攻击&#xff0c;全称分布式拒绝服务攻击&#xff08;Distributed Denial of Service attack&#xff09;&#xff0c;是一种常见的网络安全攻击方式。以下是对DDoS攻击的详细解释: DDoS攻击是指攻击者利用大量被控制的计算机或设备&#xff…

如何查看JDK使用的垃圾收集器

在Java开发中&#xff0c;垃圾收集器&#xff08;Garbage Collector, GC&#xff09;是管理内存的关键组件&#xff0c;不同的垃圾收集器对应用性能有着显著影响。了解当前JDK使用的垃圾收集器对于性能调优至关重要。本文将介绍如何查看JDK使用的垃圾收集器。 JDK中的垃圾收集…

提升Android Studio开发体验:使用Kelp插件实现颜色和图标预览

提升Android Studio开发体验&#xff1a;使用Kelp插件实现颜色和图标预览 在Android开发中&#xff0c;自动补全功能对于提高开发效率至关重要。然而&#xff0c;默认的Android Studio并不能预览颜色和图标&#xff0c;这使得开发者在选择资源时常常感到困惑。本文将介绍如何使…

Linux中cat命令的英文含义

我之前一直在想cat不是猫的意思吗&#xff0c;但是cat命令在Linux中并不是指"猫"这个动物&#xff0c;而是来源于它的功能&#xff1a;concatenate&#xff08;连接&#xff09;和typeset&#xff08;打印&#xff09;。这个命令的名称是这两个功能的首字母缩写。尽管…

「电子数据」龙信助力鞍山市公安局电子数据取证竞赛

文章关键词&#xff1a;电子数据取证、服务支持、电子数据取证竞赛服务、取证人才培养 为进一步推动电子数据取证分析专业人才队伍建设&#xff0c;不断提高电子数据取证分析能力&#xff0c;7月1日&#xff0c;鞍山市公安局网安支队举办了电子数据取证竞赛&#xff0c;并取得…

【SOLID原则前端中的应用】里氏替换原则(Liskov Substitution Principle,LSP)- vue3示例

里氏替换原则&#xff08;Liskov Substitution Principle&#xff0c;LSP&#xff09;规定&#xff0c;子类对象必须能够替换父类对象&#xff0c;并且程序的行为保持不变。 在Vue 3中&#xff0c;这意味着我们在创建可替换的组件时&#xff0c;应该确保子组件能够完全替代父组…

杭州叉车A38老款国二 车辆维修与保养

发动机参数 更换缸垫 故障表现特征&#xff1a; 1. 发动机发动风扇端有异响&#xff0c;喷气 2. 水箱加水后外冒有水气泡 车型&#xff1a; 新柴490B 预估市场平均价格&#xff1a; 25一个 发动机-气门间隙调整 气门间隙大小&#xff1a; 经询问相关师傅&#xff0c;此次调整…

物联网综合实验平台-物联网实验实训教学平台-物联网实验箱

物联网&#xff08;IoT&#xff09;是一种连接性技术&#xff0c;将各种设备和物品连接到互联网&#xff0c;通过数据的收集和分析实现更智能的决策和操作。在《“十四五”数字经济发展规划》中&#xff0c;物联网被明确提出&#xff0c;被视为数字经济时代的基础设施。当前&am…

【JavaWeb】利用IntelliJ IDEA 2024.1.4 +Tomcat10 搭建Java Web项目开发环境(图文超详细)

1、启动IntelliJ idea 2024.1.4 在欢迎页面&#xff0c;请确认好版本。因为不同的版本&#xff0c;搭建项目过程不太一样。 点击&#xff0c;新建项目。如图&#xff1a; 2、新建项目 在新建项目界面&#xff0c;选择java&#xff0c;在右侧信息模块内&#xff0c;根据个人情…

C语言中函数的声明和创建

C语言的函数创建和java函数有有一定的区别&#xff1a;如下示例&#xff1a; fun.h文件 fun.c文件 main.c文件 或这简单一点可以这样写&#xff0c; 声明和定义的差异&#xff1a; 函数分类

加速度传感器信号处理注意事项

1 传感器分类 对于压电式压力传感器而言&#xff0c;输出信号是最重要的选择标准之一。压电式压力传感器与电子电路相连&#xff0c;电子电路将传感器产生的电荷成比例转换为电压。 如果选用外部设备&#xff08;电荷放大器&#xff09;充当电子元件&#xff0c;则称其为电…

线程池概念的详解

前言&#x1f440;~ 上一章我们介绍了什么是定时器以及如何去实现一个定时器&#xff0c;今天我们来讲解在多线程中同样很重要的一个内容线程池 线程池的出现 线程池概念 标准库中的线程池 工厂模式 newCacheThreadPool方法 newFixedThreadPool方法 ThreadPoolExecutor…

2024年广东省食品安全管理员考试精选练习题库。

16.食品流通可的单次有效期为&#xff08;&#xff09;年。 A.2 B.3 C.5 答案&#xff1a;B 17.无公害农产品的标志是&#xff08;&#xff09;的。 A.绿颜色 B.绿橙两色 答案&#xff1a;B 18.与食品安全有关的"危险温度带"是指适合大多数致病菌增殖的温度…

基于贝叶斯优化的卷积神经网络-循环神经网络混合模型的的模拟股票时间序列预测(MATLAB R2021B)

将机器学习和深度学习方法运用到股市分析中, 不仅具有一定的理论价值, 也具有一定的实践价值。从理论价值上讲, 中国的量化投资技术&#xff08;投资观念、方法与决策等&#xff09;还不够成熟, 尚处在起步阶段, 能够将量化投资技术运用到投资决策中的公司寥寥无几。目前, 国内…

初识单片机

单片机 英文 Micro Controller Unit&#xff08;MCU&#xff09; 1.内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能 2.单片机的任务是信息采集&#xff08;依靠传感器&#xff09;、处理&#xff08;依靠CPU&#xff09;和硬件设备&#…

pycharm无法添加python解释器的解决方法

出现该错误的原因是先前创建过重名的解释器&#xff08;虚拟环境&#xff09;&#xff0c;在pycharm配置中没有完全删除干净。解决方法如下&#xff1a; 首先在文件->设置界面&#xff0c;找到解释器设置。 然后先按图所示点击全部显示虚拟环境&#xff1a; 接着将无法添…