React Native Video安卓端无法全屏播放问题求助
首先得说,你遇到的这个问题在RN 0.57.7 + react-native-video的组合里挺常见——Android端的全屏播放需要兼顾配置、布局和Orientation的协同处理,不像iOS那样开箱即用。咱们一步步来排查和修复:
一、先补全Android核心配置(最容易忽略的坑)
AndroidManifest.xml里的Activity配置是关键,如果没加屏幕旋转的相关配置,旋转时Activity会直接重启,导致视频状态丢失、全屏失效。
找到你的android/app/src/main/AndroidManifest.xml,找到对应的<activity>标签(一般是MainActivity),添加android:configChanges="keyboard|keyboardHidden|orientation|screenSize":
<activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" <!-- 新增这行 --> android:windowSoftInputMode="adjustResize"> ... </activity>
二、代码逻辑的针对性修复
1. 调整Orientation切换时机
你现在在componentDidMount里直接锁横屏,但此时用户还没点击播放,界面显示的是封面图,强制横屏不仅体验奇怪,还可能导致后续播放的布局适配异常。应该改成用户点击播放时再切换横屏,退出时切回竖屏:
修改播放按钮的点击事件:
<TouchableOpacity onPress={() => { this.setState({playing:true}); Orientation.lockToLandscape(); // 点击播放才切换横屏 }} > <Image source={require("../assets/Common/Play/playIcon.png")}/> </TouchableOpacity>
同时优化返回按钮的逻辑,先重置播放状态再切竖屏:
goToHome(){ this.setState({playing: false}); // 先停止播放 Orientation.lockToPortrait(); this.props.navigation.goBack(); }
2. 筛选Android兼容的Vimeo视频链接
Vimeo返回的files数组里可能包含Android不支持的格式(比如webm),直接取第一个链接可能刚好是iOS优先的格式,导致Android播放异常。咱们筛选出MP4格式的视频,优先选高清版本:
修改fetchVimeoVideo里的文件处理逻辑:
const jsonResponse = await response.json(); let { files} = jsonResponse; if (response.status != 200) { alert(response.status) } // 筛选MP4格式,按画质从高到低排序,取第一个 const androidCompatibleVideo = files .filter(file => file.type === 'video/mp4') .sort((a, b) => b.quality - a.quality)[0]; // 找不到MP4的话 fallback 到原数组第一个 const targetVideo = androidCompatibleVideo ? [androidCompatibleVideo] : [files[0]]; await this.setState({ videoFileArr: targetVideo, loading: false });
3. 优化Video组件的配置与布局
你当前的Video组件缺少两个关键配置,布局样式也可以调整得更适配横竖屏:
- 添加
resizeMode="cover":确保视频填充整个屏幕,避免黑边 - 添加
onFullscreen回调:同步全屏状态与Orientation - 用
flex:1代替绝对定位,让视频自动适配屏幕尺寸
修改后的Video组件:
<Video source={{ uri: this.state.videoFileArr[0].link}} ref={ ref => this.player = ref } onBuffer={this.onBuffer} onError={this.videoError} style={styles.backgroundVideo} controls={true} paused={false} fullscreen={true} resizeMode="cover" // 确保视频填充屏幕 onFullscreen={(isFullscreen) => { // 同步全屏状态和Orientation if (isFullscreen) { Orientation.lockToLandscape(); } else { Orientation.lockToPortrait(); this.setState({playing: false}); } }} />
对应的样式调整:
const styles = StyleSheet.create({ container:{ flex: 1, }, backgroundVideo: { flex: 1, width: '100%', height: '100%', }, });
4. 消除SafeAreaView的影响
SafeAreaView在横屏时会自动添加左右padding,导致视频无法真正全屏。可以根据播放状态动态调整它的样式:
<SafeAreaView style={{ flex: 1, padding: this.state.playing ? 0 : undefined }}> ... </SafeAreaView>
三、最后验证
做完这些修改后,建议先清理Android缓存再重新编译:
cd android && ./gradlew clean && cd .. && react-native run-android
点击播放按钮后,应该会自动切换到横屏,视频填满整个屏幕,控件正常显示;点击返回按钮会切回竖屏,回到之前的界面。
内容的提问来源于stack exchange,提问作者Sahadev




