Android中实现沉浸式布局并支持软键盘弹出不遮挡布局

效果图

步骤:

1.style.xml文件
<style name="NoActionBar" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <!-- 让内容布局延伸到状态栏下方 -->
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:windowTranslucentStatus">false</item>
    </style>
2.AndroidMainfest.xml文件
 <activity
            android:name=".ChatActivity"
            android:exported="true"
            android:screenOrientation="portrait"
            android:theme="@style/NoActionBar"
            android:windowSoftInputMode="stateVisible|adjustResize" />
3.工具类

说明:

 bottom = item.bottom.coerceAtLeast(systemBars.bottom)//优先响应软键盘,否则留出底部导航按钮空间
bottom = item.bottom//软键盘不遮挡布局,需要预留出软键盘空间,不会预留底部导航按钮空间

package com.hat

import android.app.Activity
import android.graphics.Color
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import com.zbxh.chat.utils.DefaultDarkScrim
import com.zbxh.chat.utils.DefaultLightScrim
import com.zbxh.chat.utils.SystemBarStyle
import com.zbxh.chat.utils.enableEdgeToEdge

class SetSystemBars {
    companion object{
        fun setupSystemBars(activity: Activity,view: View) {
            // 沉浸式状态栏配置
            WindowCompat.setDecorFitsSystemWindows(activity.window, false)
            activity.window.statusBarColor = Color.TRANSPARENT
            val insetsListener = OnApplyWindowInsetsListener { view, insets ->
                val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
                val item = insets.getInsets(WindowInsetsCompat.Type.ime())
                view.updatePadding(
                    top = 0,    // 顶部留出状态栏空间
                    bottom = item.bottom.coerceAtLeast(systemBars.bottom),//优先响应软键盘,否则留出导航栏空间
                    //bottom = item.bottom,//软键盘不遮挡布局,需要预留出软键盘空间
                    left = systemBars.left,
                    right = systemBars.right
                )
                insets
            }
            ViewCompat.setOnApplyWindowInsetsListener(view, insetsListener)
        }
        fun setupSystemBars2(activity: Activity) {
            (activity as AppCompatActivity).enableEdgeToEdge(
                SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT),
                SystemBarStyle.auto(DefaultLightScrim, DefaultDarkScrim))
        }
    }
}
4.使用
package com.chat;

public class ChatActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //一定要在setContentView前调用
        SetSystemBars.Companion.setupSystemBars(this,findViewById(R.id.chat));//R.id.chat是界面中根布局的ID
        setContentView(R.layout.activity_chat_main);
    }
}

### 设置沉浸式UI以避免虚拟导航栏遮挡内容 在Android应用开发中,为了实现沉浸式界面避免虚拟导航栏遮挡内容,可以通过隐藏系统UI元素(如状态栏和导航栏)以及合理设置布局参数来达到目的。以下是一些关键步骤: - **隐藏虚拟导航栏** 可以通过设置特定的系统UI标志位来隐藏虚拟导航栏。对于API 19及以上版本,可以使用`SYSTEM_UI_FLAG_HIDE_NAVIGATION`结合`SYSTEM_UI_FLAG_IMMERSIVE_STICKY`标志来实现沉浸式体验[^1]。示例代码如下: ```java protected void hideBottomUIMenu() { if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { View v = this.getWindow().getDecorView(); v.setSystemUiVisibility(View.GONE); } else if (Build.VERSION.SDK_INT >= 19) { View decorView = getWindow().getDecorView(); int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN; decorView.setSystemUiVisibility(uiOptions); } } ``` 这段代码可以在Activity的`onCreate`方法里调用一次,且在有需要的地方也可以再次调用以确保导航栏始终处于隐藏状态。 - **调整布局参数** 在设计布局时,给底部控件添加额外的边距或填充可以帮助防止它们被虚拟导航栏覆盖。例如,在XML布局文件中为父布局设置合适的`android:paddingBottom`值,或者动态计算虚拟导航栏的高度在运行时调整布局参数。 - **利用系统提供的工具类处理窗口插入问题** Android提供了`ViewCompat.setOnApplyWindowInsetsListener`等方法来更灵活地控制视图与系统UI之间的交互。这种方法允许开发者监听窗口插入的变化,据此调整布局,从而有效避开虚拟导航栏的影响。 - **自定义样式文件** 对于API 21及以上版本,可以通过创建特定资源目录(比如`values-21`),在其中定义主题样式禁用系统绘制状态栏和导航栏背景,这样可以避免内容被遮挡。同时,也可以考虑将状态栏和导航栏设为透明,使应用内容能够延伸到整个屏幕区域。 - **使用ConstraintLayout特性** 使用`ConstraintLayout`及其引导线、屏障等功能,可以更加精细地控制同屏幕尺寸下的布局行为,有助于避开虚拟导航栏带来的遮挡问题。 - **软键盘适配** 如果问题是由于软键盘弹出导致的内容遮挡,则应该检查适当设置`android:fitsSystemWindows`属性以及合理运用`ScrollView`或`NestedScrollView`来保证输入框可见性。 这些策略可以根据具体需求选择合适的方式来实施,通常结合多种方法能够达到最佳效果。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值