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

打印 上一主题 下一主题

主题 518|帖子 518|积分 1554

简介

Android V 上默认会使用全面屏兼容方式,影响应用显示,导致应用内跟导航标题重合,无法点击上移的内容。
   默认情况下,如果应用以 Android 15(API 级别 35)为目标平台,在搭载 Android 15 的装备上,应用默认接纳全屏。
  办理方案

先说适配方案,后面有官方文档的先容说明变更内容、应用自查方法和配置建议。
方法:实现无边框应用。
   怎样检查应用尚未实现无边框
  
  如果您的应用还没有全面屏,那么您很可能会受到影响。除了针对已经接纳无边框的应用的情况之外,您还应思量以下事项:
  

  • 如果您的应用在 Compose 中使用 Material 3 组件 (androidx.compose.material3)(比方 TopAppBar、BottomAppBar 和 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 组件(比方 BottomNavigationView、BottomAppBar、NavigationRailView 或 NavigationView)均可处理边衬区,无需实行额外的操作。不过,如果使用 AppBarLayout,则需要添加 android:fitsSystemWindows="true"。
  • 对于自界说可组合项,请手动将边衬区作为内边距应用。如果您的内容在 Scaffold 内,您可以使用 Scaffold 内边距值使用边衬区。否则,请使用某个 WindowInsets 应用内边距。
  • 如果您的应用使用视图和 BottomSheet、SideSheet 或自界说容器,请使用 ViewCompat.setOnApplyWindowInsetsListener 应用内边距。对于 RecyclerView,请使用此监听器应用内边距,并添加 clipToPadding="false"。
  (一)针对传统的Java传统视图参考方案(无Compose使用)
【Java】创建界面时,设置属性 fitsSystemWindows属性为 true

如果做成插件化,没有使用Activity结构可配置,如PreferenceScreen中没有android:fitsSystemWindows="true"配置,且设置activitybase.xml线性结构此属性也无法办理,可选择在onCreateView生命周期中渲染界面。
  1. public class MainPref extends PreferenceFragmentBase
  2.         implements Preference.OnPreferenceChangeListener {
  3.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  4.         View rootView = super.onCreateView(inflater, container, savedInstanceState);
  5.         Log.d(TAG, "onCreateView: rootView = "+ rootView + ", setFitsSystemWindows=true.");
  6.         if (rootView != null) {
  7.             rootView.setFitsSystemWindows(true);
  8.         }
  9.         return rootView;
  10.     }
复制代码
Note:在一个包含 Fragment 的 Activity 中,onCreate()方法会先被调用,然后再调用 Fragment 的onCreateView()方法。 
(二)针对Compose的方案:
1、在build.gradle 添加编译依赖
  1. dependencies {
  2.     implementation "androidx.core:core-ktx:1.6.0" // 当前释放最新应该是1.6.0,可以需修改成以后更新版本
  3.     implementation "androidx.appcompat:appcompat:1.3.1"
  4.     implementation "androidx.constraintlayout:constraintlayout:2.0.4"
  5. }
复制代码
2、【XML】修改manifest配置结构 fitsSystemWindows属性为 true
  1. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:app="http://schemas.android.com/apk/res-auto"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:fitsSystemWindows="true"
  7.     android:id="@+id/main_layout"
  8.     tools:context=".MainActivity">
  9. </androidx.constraintlayout.widget.ConstraintLayout>
复制代码
3、【Java】修改Activity创建逻辑
   默认情况下,每个 ComposeView 都会使用 WindowInsetsCompat 级别使用的所有边衬区。如需更改此默认行为,请将 ComposeView.consumeWindowInsets 设置为 false。
  1. protected void onCreate(Bundle savedInstanceState) {
  2.     super.onCreate(savedInstanceState);
  3.     setContentView(R.layout.activity_main);
  4.     //拿到自定义id的布局进行操作
  5.     ConstraintLayout mainLayout = findViewById(R.id.main_layout);
  6.     ViewCompat.setOnApplyWindowInsetsListener(mainLayout, (v, windowInsets) -> {
  7.         WindowInsetsCompat insetsCompat = ViewCompat.getRootWindowInsets(v);
  8.         if (insetsCompat != null) {
  9.             Insets insets = insetsCompat.getInsets(WindowInsetsCompat.Type.systemBars());
  10.             Log.d(TAG, "left = " + insets.left + ", top = " + insets.top +
  11.                 ", right = " + insets.right + ", bottom = " + insets.bottom);
  12.             v.setPadding(insets.left, insets.top, insets.right, insets.bottom);
  13.         } else {
  14.             Log.d(TAG, "insetsCompat is null");
  15.         }
  16.         // 获取 WindowInsetsControllerCompat 实例
  17.         WindowInsetsControllerCompat windowInsetsController = ViewCompat.getWindowInsetsController(v);
  18.         if (windowInsetsController != null) {
  19.             // 设置状态栏图标和文字为深色
  20.             windowInsetsController.setAppearanceLightStatusBars(true);
  21.         }
  22.         // Return CONSUMED if you don't want want the window insets to keep passing
  23.         // down to descendant views.
  24.         return WindowInsetsCompat.CONSUMED;
  25.     });
  26. }
复制代码
官方文档

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 装备上非全屏的应用   
全屏欺压应用

2、当API和体系都是Android 15时,会受到全面屏负面影响,导致top Bar和导航栏异常重合问题。
   由于 Android 15 全屏欺压措施,现在许多元素被状态栏、“三按钮”导航栏或刘海屏隐藏。隐藏界面包括 Material 2 顶部应用栏、悬浮操作按钮和列表项。
   
     以 Android 15(API 级别 35)为目标平台且在 Android 15 装备上为全屏的应用   
无边框应用

3、在 Android 15 装备上接纳无边框应用,并应用边衬区以便不隐藏界面。
   
     以 Android 15(API 级别 35)为目标平台的应用,在 Android 15 装备上接纳无边框应用    如需了解应用边衬区的其他留意事项,请参阅无边框视图和无边框 Compose 指南。

配置说明

如果您的应用以 Android 15 或更高版本为目标平台,Configuration 将不再排除体系栏。如果您在 Configuration 类中使用屏幕尺寸盘算结构,则应根据需要将其更换为合适的 ViewGroup、WindowInsets 或 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() 就一直以这种方式运行。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

前进之路

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表