You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11+ React Native中如何隐藏Modal等组件的导航栏?

React Native Android 11+ 沉浸式导航栏问题修复

问题描述

已通过在MainActivity.java中添加代码实现大部分页面隐藏导航栏,但Android 11及以上版本中,弹出React Native的Modal、Alert或软键盘时,系统导航栏会重新显示,需要解决该问题以保持全程沉浸式效果。

解决方案

核心思路

针对Android 11+的WindowInsets机制,通过监听窗口状态变化、统一配置窗口属性,确保Modal、Alert弹出或软键盘激活时,导航栏始终保持隐藏状态。

修改后的完整代码

import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import com.facebook.react.ReactActivity;

public class MainActivity extends ReactActivity {

    @Override
    protected void onStart() {
        super.onStart();
        setupImmersiveMode();
    }

    @Override
    protected void onResume() {
        super.onResume();
        setupImmersiveMode();
    }

    private void setupImmersiveMode() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            hideNavAndroid11();
            // 监听窗口Insets变化,Modal/软键盘触发时重新隐藏导航栏
            getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> {
                hideNavAndroid11();
                return v.onApplyWindowInsets(insets);
            });
        } else {
            hideNavAndroid10();
            getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(visibility -> {
                if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
                    hideNavAndroid10();
                }
            });
        }
    }

    public void hideNavAndroid11() {
        final Window window = getWindow();
        try {
            runOnUiThread(() -> {
                WindowInsetsController insetsController = window.getInsetsController();
                if (insetsController != null) {
                    insetsController.hide(WindowInsets.Type.navigationBars() | WindowInsets.Type.statusBars());
                    insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
                }
                // 让布局延伸到系统栏区域,避免底部留白
                window.setFlags(
                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                );
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void hideNavAndroid10() {
        try {
            runOnUiThread(() -> {
                final View decorView = getWindow().getDecorView();
                decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                );
                getWindow().setFlags(
                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                );
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 窗口重新获得焦点时(如Modal关闭后),重新启用沉浸式模式
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            setupImmersiveMode();
        }
    }
}

关键改动说明

  • Insets变化监听:Android 11+中通过setOnApplyWindowInsetsListener捕获Modal、Alert、软键盘触发的窗口状态变化,每次变化后重新执行隐藏导航栏逻辑。
  • FLAG_LAYOUT_NO_LIMITS:强制窗口布局延伸到系统栏区域,避免导航栏隐藏后出现底部空白。
  • onWindowFocusChanged:确保Modal关闭、页面重新获得焦点时,沉浸式模式自动恢复。

内容的提问来源于stack exchange,提问作者Żabojad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 10:02:36