调用setOnApplyWindowInsetsListener导致系统栏颜色重置如何解决?
问题原因
你将ViewCompat.setOnApplyWindowInsetsListener设置到根View时,会覆盖Android系统默认的窗口Insets处理逻辑,主题中配置的状态栏、导航栏颜色渲染属于默认处理逻辑的一部分,你直接返回原Insets没有触发后续的默认渲染流程,所以导致系统栏颜色被重置。
解决方案
方案1:保留WindowInsets监听,补全默认处理逻辑
不要直接返回Insets,处理完滚动逻辑后手动调用系统默认的Insets处理方法即可,修改代码如下:
View rootView = findViewById(R.id.chat_root_view).getRootView(); ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> { // 先执行滚动逻辑 int bottomInset = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom; // 只有软键盘弹出(底部Insets大于0)时才触发滚动,避免不必要的滚动操作 if (bottomInset > 0 && recyclerView.getAdapter() != null) { recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1); } // 调用系统默认处理逻辑,保留主题配置的系统栏颜色等效果 return ViewCompat.onApplyWindowInsets(v, insets); });
补充:添加软键盘弹出判断可以避免其他Insets变化(比如状态栏、导航栏状态变更)时触发无意义的滚动
方案2:使用布局变化监听实现需求,不干扰WindowInsets流程
如果不需要处理复杂的Insets逻辑,可以用更轻量的全局布局监听实现软键盘弹出判断,完全不会影响系统栏的原有配置:
View rootView = findViewById(R.id.chat_root_view); rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> { Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); int screenHeight = rootView.getRootView().getHeight(); // 计算布局被遮挡的高度,超过屏幕高度1/4则判定为软键盘弹出 int keypadHeight = screenHeight - r.bottom; if (keypadHeight > screenHeight * 0.25 && recyclerView.getAdapter() != null) { recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1); } });
该方案适配所有Android版本,无需处理Insets相关的兼容性问题
内容的提问来源于stack exchange,提问作者Sujith S Manjavana
相关产品推荐
相关产品推荐

