Android 15+(SDK 35+)下纯代码实现的RelativeLayout自定义View如何适配Edge-to-Edge特性
Android 15+(SDK 35+)下纯代码实现的RelativeLayout自定义View如何适配Edge-to-Edge特性
嘿,我来帮你搞定这个Edge-to-Edge适配的问题!你已经在Activity里调用了EdgeToEdge.enable(this),这步做的没错,接下来只需要给你的自定义SurvivorLayout和内部的滚动组件做一些针对性调整就行,具体步骤我给你拆解清楚:
1. 给自定义根布局(SurvivorLayout)添加WindowInsets监听
因为你的布局是纯代码构建的,需要手动处理系统窗口的内边距(insets),避免内容被状态栏、导航栏挡住。在SurvivorLayout的构造函数里,等所有组件初始化完成后,添加这段代码:
// 用ViewCompat兼容低版本,SDK35也能正常使用 ViewCompat.setOnApplyWindowInsetsListener(this, (view, insets) -> { // 获取系统栏(状态栏+导航栏)的内边距值 WindowInsetsCompat windowInsets = insets; Insets systemBarsInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // 给根布局设置padding,让所有子组件自动避开系统栏区域 view.setPadding( systemBarsInsets.left, systemBarsInsets.top, systemBarsInsets.right, systemBarsInsets.bottom ); // 如果不需要子组件再单独处理insets,就返回CONSUMED;若要传递给子组件处理,返回insets即可 return WindowInsetsCompat.CONSUMED; });
2. 调整内部滚动组件的适配逻辑
你的布局里包含ScrollView和HorizontalScrollView,如果希望滚动内容能自然延伸到系统栏下方(滚动时内容可以跑到半透明的系统栏后面),需要给这些滚动组件单独设置:
// 以scrollViewC为例,在初始化它的时候添加: scrollViewC.setFitsSystemWindows(false); // 用ViewCompat做版本兼容 ViewCompat.setFitsSystemWindows(scrollViewC, false); // 要是想让滚动组件的内容完全填充到系统栏下方,还可以给它的子视图(比如tableC)调整padding,不过一般上面的设置就足够了
3. 确认Activity的窗口/主题设置正确
Edge-to-Edge需要系统栏是透明的,并且允许内容延伸到系统栏区域。如果你的主题还没配置,要么在styles.xml里修改:
<style name="SurvivorActivityTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <!-- 透明状态栏和导航栏 --> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:navigationBarColor">@android:color/transparent</item> <!-- 允许窗口绘制系统栏背景(确保透明生效) --> <item name="android:windowDrawsSystemBarBackgrounds">true</item> <!-- 让内容延伸到系统栏和刘海屏区域 --> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> <!-- 状态栏文字颜色适配,根据主题背景设置true(浅色状态栏用深色文字)或false --> <item name="android:windowLightStatusBar">true</item> </style>
或者在SurvivorActivity的onCreate里动态设置(适合纯代码场景):
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); // 动态设置窗口属性 Window window = getWindow(); window.setStatusBarColor(Color.TRANSPARENT); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { window.setNavigationBarColor(Color.TRANSPARENT); } // 允许内容延伸到系统栏和刘海屏区域 window.getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION ); // 后续设置ContentView setContentView(new SurvivorLayout(this, sList)); }
最后检查点
- 确保
SurvivorLayout构造函数里的insets监听代码,是在所有组件初始化完成后添加的,不然可能找不到对应的滚动组件。 - 如果某些子视图需要特殊处理(比如顶部标题栏要紧贴状态栏),可以单独给该子视图设置padding,覆盖根布局的padding。
这样调整后,你的纯代码自定义View就能完美适配SDK35+的Edge-to-Edge特性啦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

