如何在API 36中调整布局避免内容被摄像头和Home键遮挡?
解决API 36下内容被系统UI遮挡的布局调整方案
针对API 36出现的内容被前置摄像头、Home键遮挡的问题,结合你使用LinearLayout/ConstraintLayout且无ActionBar的场景,可通过以下方式调整:
1. 启用系统自动适配边距
在根布局添加android:fitsSystemWindows="true"属性,系统会自动为布局添加合适的padding,避开状态栏、刘海和导航栏区域:
- 对于LinearLayout:
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" ...> <!-- 子控件 --> </LinearLayout>
- 对于ConstraintLayout:
<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" ...> <!-- 子控件 --> </androidx.constraintlayout.widget.ConstraintLayout>
2. 手动监听WindowInsets实现精准适配
如果自动适配无法满足需求,可通过代码动态处理系统Insets,自定义布局的padding:
Kotlin示例
val rootView = findViewById<View>(R.id.root_layout) rootView.setOnApplyWindowInsetsListener { view, insets -> // 获取状态栏和导航栏的Insets val statusBarTop = insets.getInsets(WindowInsets.Type.statusBars()).top val navBarBottom = insets.getInsets(WindowInsets.Type.navigationBars()).bottom // 动态设置padding,避开遮挡区域 view.setPadding(view.paddingLeft, statusBarTop, view.paddingRight, navBarBottom) insets }
Java示例
View rootView = findViewById(R.id.root_layout); rootView.setOnApplyWindowInsetsListener((view, insets) -> { int statusBarTop = insets.getInsets(WindowInsets.Type.statusBars()).top; int navBarBottom = insets.getInsets(WindowInsets.Type.navigationBars()).bottom; view.setPadding(view.getPaddingLeft(), statusBarTop, view.getPaddingRight(), navBarBottom); return insets; });
3. 用ConstraintLayout的Guideline绑定系统Insets
在ConstraintLayout中添加绑定系统边距的Guideline,将内容控件约束到Guideline上,确保不被遮挡:
<!-- 顶部Guideline,避开状态栏/刘海 --> <androidx.constraintlayout.widget.Guideline android:id="@+id/top_guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_insetEdge="top"/> <!-- 底部Guideline,避开导航栏/Home键 --> <androidx.constraintlayout.widget.Guideline android:id="@+id/bottom_guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_insetEdge="bottom"/>
之后将顶部标题控件约束到top_guideline,底部内容控件约束到bottom_guideline即可。
4. 调整主题配置
- 避免主题中设置
android:windowFullscreen="true",如果需要全屏显示,必须配合手动Insets处理。 - 添加
android:windowLayoutInDisplayCutoutMode="shortEdges"到主题中(API 28+支持),让布局自动避开刘海区域:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> </style>
内容的提问来源于stack exchange,提问作者Chu Man Ki Morris
相关产品推荐
相关产品推荐

