React Native Android端全屏适配问题(含Modal弹窗场景)
我之前也碰到过完全一样的问题!不用修改RN源码的话,有几个靠谱的解决方案,你可以按需求选择:
方案一:利用NativeModules暴露全屏方法,在Modal生命周期回调中触发
你已经在MainActivity里写了goFullScreen()方法,只需要把这个方法暴露给React端,然后在Modal显示/隐藏时调用即可:
1. 暴露原生方法到React端
在MainActivity.java中添加@ReactMethod注解,把全屏方法暴露出去:
import com.facebook.react.bridge.ReactMethod; public class MainActivity extends ReactActivity { // 你的goFullScreen方法... @ReactMethod public void triggerFullScreen() { goFullScreen(); } // 其他原有代码... }
2. React端调用方法控制全屏
在你的Modal组件中,导入NativeModules并在对应回调里调用方法:
import { NativeModules, Modal } from 'react-native'; const { MainActivity } = NativeModules; // 你的组件代码 function YourModalComponent() { const [modalVisible, setModalVisible] = useState(false); return ( <Modal visible={modalVisible} onShow={() => MainActivity.triggerFullScreen()} onHide={() => MainActivity.triggerFullScreen()} // 其他Modal属性 > {/* 弹窗内容 */} </Modal> ); }
原理:Modal弹出时会创建独立的Dialog窗口,这个窗口不会自动继承主Activity的SystemUiFlags,我们在它显示时主动调用全屏方法,强制把当前窗口的UI标志设置为沉浸式;关闭弹窗后再调用一次,确保主界面回到全屏状态。
方案二:使用第三方库快速控制沉浸式模式
推荐使用react-native-immersive库,它封装了Android的沉浸式逻辑,无需自己写原生代码:
1. 安装库
npm install react-native-immersive --save # 或者用yarn yarn add react-native-immersive
RN 0.60+版本会自动完成链接,无需额外操作。
2. 在Modal回调中设置沉浸式
import Immersive from 'react-native-immersive'; import { Modal } from 'react-native'; function YourModalComponent() { const [modalVisible, setModalVisible] = useState(false); return ( <Modal visible={modalVisible} onShow={() => Immersive.setImmersive(true)} onHide={() => Immersive.setImmersive(true)} // 其他Modal属性 > {/* 弹窗内容 */} </Modal> ); }
这个库会自动处理不同窗口下的SystemUiFlags设置,包括Modal弹窗场景,非常省心。
为什么之前修改主题的方式无效?
你修改的AppTheme是主Activity的主题,但RN的Modal弹窗使用的是独立的Dialog主题(默认是Theme.ReactNative.AppCompat.Dialog),不会继承Activity的全屏配置,所以只改Activity主题无法影响Modal窗口。而且单纯设置windowFullscreen无法实现SYSTEM_UI_FLAG_IMMERSIVE_STICKY的沉浸式粘性效果,这也是导航栏关闭后不消失的原因。
内容的提问来源于stack exchange,提问作者pushingbits

