Android刘海屏适配
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android刘海屏适配相关的知识,希望对你有一定的参考价值。
参考技术A 刘海屏幕的适配,在全面屏设置下,顶部有刘海的区域,有的会导致刘海把标题栏等内容遮盖如下图,这是美团的统一版本在小米和华为上的适配,可以看到小米的未遮挡内容,但在华为设备上,明显刘海遮住了一部分内容,目前手里只有这两台设备,所以没有更多机型测试,不过根据上线APP反馈,目前这个方法可以满足。此博文为笔记内容,所以内容不多如果统一留出固定的高度,会在不同设备上造成不同的效果,现在使用动态计算顶部状态栏高度然后预留高度,防止被异形屏遮挡情况,使用之后的效果如下图
使用方法,在布局上设置一个占位条,需要适配的引用进来,因为有些布局是不用设置的
Android 全面屏处理(适配挖孔屏刘海屏) kotlin
测试机:
Android 11 的 Xiaomi MI MAX 3
Android 12 的 Xiaomi K40 Pro
测试方法:
1. 该方法在api30后提示已经过时 在onCreat()方法中,setContentView()前使用。
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
测试结果:Android11和Android12均有效,但Android12的挖孔屏区域无效
2. 沉浸模式,查询到:Android系统到了4.4以后才提供沉浸式体验的支持。当设置透明效果后,4.4以下无效果,4.4~5.0全透明,5.0以上半透明;Android沉浸式模式的本质就是全屏化。
//该方法是从官网复制过来的,效果不如意
private fun hideSystemBars()
val windowInsetsController =
ViewCompat.getWindowInsetsController(window.decorView) ?: return
// Configure the behavior of the hidden system bars
windowInsetsController.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// Hide both the status bar and the navigation bar
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
测试结果:Android11无效,Android12有效,Android12的挖孔屏区域无效。Android11获取windowInsetsController为null
//这是从别人那里拷过来的(csdn):https://blog.csdn.net/qq_32664007/article/details/126279919
private fun hideSystemBars(window: Window)
//隐藏状态栏和导航栏 以及交互
WindowInsetsControllerCompat(window, window.decorView).let
//隐藏状态栏和导航栏
it.hide(WindowInsetsCompat.Type.systemBars())
//交互效果
it.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
测试结果:Android11无效,Android12有效,Android12的挖孔屏区域无效。
3.该方法在ide里提示已过时,在官网上未提示
val decorView = window.decorView
decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
测试结果:Android11和Android12均有效,但Android12的挖孔屏区域无效
4.该方法对测试机均有部分效过
WindowCompat.setDecorFitsSystemWindows(window, false)
测试结果:Android11和Android12的activity绘制区域均将状态栏的区域绘制成功,但状态栏依然透明显示,Android12的挖孔屏区域无效,效果如图(按钮绘制在状态栏的位置上):
5.使用主题
<item name="android:windowFullscreen">true</item>
测试结果:Android11有效,Android12有效,Android12的挖孔屏区域无效。
6.挖孔屏处理方式
//允许window 的内容可以上移到刘海屏状态栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
val lp = window.attributes
lp.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
window.attributes = lp
测试结果:Android12 挖孔屏有效
封装成工具类:
/**
* 沉浸模式(全屏模式)
* 设置全屏的方法
* 参数window在activity或AppCompatActivity都带有
*/
fun immersionFull(window: Window)
hideSystemBars(window)
useSpecialScreen(window)
/**
* 隐藏状态栏,显示内容上移到状态栏
*/
private fun hideSystemBars(window: Window)
//占满全屏,activity绘制将状态栏也加入绘制范围。
//如此即使使用BEHAVIOR_SHOW_BARS_BY_SWIPE或BEHAVIOR_SHOW_BARS_BY_TOUCH
//也不会因为状态栏的显示而导致activity的绘制区域出现变形
//使用刘海屏也需要这一句进行全屏处理
WindowCompat.setDecorFitsSystemWindows(window, false)
//隐藏状态栏和导航栏 以及交互
WindowInsetsControllerCompat(window, window.decorView).let
//隐藏状态栏和导航栏
//用于WindowInsetsCompat.Type.systemBars()隐藏两个系统栏
//用于WindowInsetsCompat.Type.statusBars()仅隐藏状态栏
//用于WindowInsetsCompat.Type.navigationBars()仅隐藏导航栏
it.hide(WindowInsetsCompat.Type.systemBars())
//交互效果
//BEHAVIOR_SHOW_BARS_BY_SWIPE 下拉状态栏操作可能会导致activity画面变形
//BEHAVIOR_SHOW_BARS_BY_TOUCH 未测试到与BEHAVIOR_SHOW_BARS_BY_SWIPE的明显差异
//BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE 下拉或上拉的屏幕交互操作会显示状态栏和导航栏
it.systemBarsBehavior =
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
/**
* 扩展使用刘海屏
*/
private fun useSpecialScreen(window: Window)
//允许window 的内容可以上移到刘海屏状态栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
val lp = window.attributes
lp.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
window.attributes = lp
然后资源目录的主题文件里添加(res->values->themes.xml):
<!-- 导航栏透明 -->
<item name="android:navigationBarColor">
@android:color/transparent
</item>
<!-- 状态栏透明 -->
<item name="android:statusBarColor">
@android:color/transparent
</item>
<!-- 不要标题栏 -->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
以上是关于Android刘海屏适配的主要内容,如果未能解决你的问题,请参考以下文章
Android 屏幕适配异形屏适配 ① ( 异形屏类型:刘海屏水滴屏挖孔屏 | 沉浸式布局刘海屏适配 | 华为手机异形屏适配注意点 )
Android 屏幕适配异形屏适配 ① ( 异形屏类型:刘海屏水滴屏挖孔屏 | 沉浸式布局刘海屏适配 | 华为手机异形屏适配注意点 )
Android 屏幕适配异形屏适配 ② ( 需要异形屏适配情况 | 需要异形屏适配的 Android 系统版本 | 刘海屏状态判定 | 异形屏适配调试 - 华为云调试 )
Android 屏幕适配异形屏适配 ② ( 需要异形屏适配情况 | 需要异形屏适配的 Android 系统版本 | 刘海屏状态判定 | 异形屏适配调试 - 华为云调试 )