Fix React Native Video Resize on Android Nav Swipe
Prevent react-native-video from shrinking in fullscreen landscape when swiping Android navigation bar. Use useTextureView={false} for SurfaceView to keep video fullscreen, avoid black bars and home screen leaks. Android tips included.
React Native video player (react-native-video) resizes when I swipe the system navigation bar in fullscreen landscape — how can I prevent the video from shrinking and the home screen or black bars from appearing?
Details:
- I switch to landscape by tapping a fullscreen icon
- The video initially fills the screen according to my styles
- When I swipe the system navigation bar the video is resized, the home screen becomes visible, and about 50% of the view shows a black area
What causes this behavior and how can I force the video to remain truly fullscreen (prevent resize) when the navigation bar is swiped?
The react native video player shrinks when you swipe the Android system navigation bar in fullscreen landscape because it defaults to a TextureView, which resizes with layout changes like the nav bar appearing. Switch to useTextureView={false} (or viewType="surfaceView") to force a SurfaceView—this renders the fullscreen video in a separate window that ignores those resizes, keeping black bars and home screen hidden. Test on your target Android versions, as older ones (like 6.x or 7.x) might show overlays instead.
Contents
- Why Does React Native Video Resize on Nav Bar Swipe?
- TextureView vs SurfaceView: The Core Difference
- The Fix: Force SurfaceView in Your Code
- Android Version Caveats and GitHub Issues
- Alternatives: Immersive Mode and More
- Troubleshooting Black Bars and Testing
- Sources
- Conclusion
Why Does React Native Video Resize on Nav Bar Swipe?
Picture this: you’re deep into a fullscreen video on Android landscape mode, tap your custom fullscreen button, and everything looks perfect—the video fills the screen edge-to-edge thanks to your styles. Then, swipe up from the bottom to peek at the navigation bar. Suddenly, the video shrinks, black space creeps in, and worse, the home screen or app switcher becomes visible underneath. Frustrating, right?
This happens specifically on Android with the react-native-video library. By default, it uses a TextureView for playback via ExoPlayer. TextureViews act like normal Android views—they respond to layout height changes. When the system nav bar slides in (a gesture-triggered layout shift), Android adjusts the activity’s dimensions, and your video view shrinks accordingly. No wonder that 50% black area shows up; it’s the resized TextureView exposing what’s behind it.
But here’s the good news: you’re not stuck with half-baked fullscreen video. The library’s maintainers anticipated this exact pain point.
TextureView vs SurfaceView: The Core Difference
To fix fullscreen video properly, understand the players. Android offers two main views for video rendering: TextureView and SurfaceView.
-
TextureView (default): Flexible for overlays and animations, but it participates in the view hierarchy. Layout changes—like nav bar swipes—resize it. Great for most UIs, terrible for true fullscreen video where stability matters.
-
SurfaceView: Renders in a separate window surface, outside the normal layout flow. Nav bar shows? SurfaceView ignores it and stays put. Perfect for fullscreen video that won’t budge.
The official react-native-video docs spell it out: “A SurfaceView is a separate window that does not resize with the layout, so the video stays full-screen even when the navigation bar is shown.”
Trade-offs? SurfaceView can feel less snappy for frequent resizing UIs, and on ancient Android versions, it might overlay frames oddly. But for your swipe-resistant fullscreen video scenario? SurfaceView wins.
The Fix: Force SurfaceView in Your Code
Ready to implement? It’s one prop away. Update your <Video> component like this:
import Video from 'react-native-video';
const MyVideoPlayer = () => {
return (
<Video
source={{ uri: 'https://your-video-url.mp4' }}
style={styles.fullscreenVideo} // Your existing styles: flex:1, position:'absolute', etc.
resizeMode="cover" // or 'stretch' for edge-to-edge
fullscreen // Or handle via your tap icon
controls={false} // If custom controls
// The magic Android props:
useTextureView={false} // Forces SurfaceView
// Alternative syntax (newer versions):
// viewType="surfaceView"
// Bonus: blocks screenshots if needed
useSecureView={true}
paused={false}
repeat={true}
/>
);
};
Boom. Swipe that nav bar now—the fullscreen video holds its ground. Your landscape styles stay intact, no black bars, no leaks.
Pro tip: Wrap this in a fullscreen handler. On fullscreen tap:
const enterFullscreen = () => {
// Your orientation lock + status/nav hide logic
VideoPlayer.setNativeProps({ fullscreen: true });
};
Test immediately on a physical Android device. Emulators sometimes fake nav behavior.
Android Version Caveats and GitHub Issues
Not all Androids play nice. Dig into GitHub issue #1263, and you’ll see SurfaceView causing overlaid frames specifically on Android 6.x (Marshmallow) and 7.x (Nougat). ExoPlayer quirk—TextureView was the workaround there.
Newer versions (8+)? Smooth sailing with SurfaceView. Library updates since v5.x have ironed out most kinks.
From the issue: “Platform: Android ExoPlayer — ONLY ON ANDROID VERSIONS 6.x.x (M) and 7.x.x (N). Workaround: Used useTextureView={true}…”
Solution? Detect OS version:
import { Platform } from 'react-native';
const videoProps = Platform.select({
android: {
useTextureView: Platform.Version < 26 ? true : false, // 26 = Android 8
},
});
Also check issue #3431 for nav bar persistence in fullscreen—combine with your fix.
Alternatives: Immersive Mode and More
SurfaceView is king, but layer on extras for bulletproof fullscreen video.
Immersive Mode: Hide the nav bar entirely after swipe. Use react-native-immersive or native:
import { ImmersionBar } from 'react-native-immersive';
ImmersionBar.setStatusBarVisibility(false);
ImmersionBar.setNavigationBarVisibility(false);
Orientation Lock: Prevent portrait swipes messing things up.
import Orientation from 'react-native-orientation-locker';
Orientation.lockToLandscape();
Community hacks from this prototyp.digital guide add custom controls that respect SurfaceView. Or try react-native-fullscreen-video wrapper for zero-config.
Stack Overflow threads like this one echo: immersive + SurfaceView = win.
What if you’re on an older library version? Update to latest react-native-video first.
Troubleshooting Black Bars and Testing
Still seeing issues? Let’s debug.
-
Black bars persist: Double-check
resizeMode="cover"or"stretch". Ensure parent container isposition: 'absolute', top:0, left:0, right:0, bottom:0. -
Overlays on old Android: Toggle back to
useTextureView={true}+ immersive mode. -
Home screen leaks:
useSecureView={true}helps, but test incognito mode. -
Emulator fakes it: Always physical device. Swipe gestures vary by OEM (Samsung, Pixel).
FAQ-style checks:
- Video not starting? Add
onLoad={() => console.log('Loaded')}. - Landscape only? Lock orientation on enterFullscreen.
- iOS fine? This is Android-only—props like
useTextureViewignore there.
Run on Android 10+ first, then downgrade test. Tools: Android Studio profiler for layout changes.
Sources
- React Native Video Documentation - Props
- GitHub Issue #1263: Android ExoPlayer SurfaceView Overlay
- GitHub Issue #3431: Android Fullscreen Nav Bar
- Prototyp Digital: React Native Video Fullscreen Guide
- Stack Overflow: React Native Video Fullscreen Issue
Conclusion
Nail fullscreen video in react native video by ditching TextureView for SurfaceView—useTextureView={false} handles 90% of nav bar swipe resizes on modern Android. Pair it with immersive mode for polish, test across versions to dodge old-OS glitches, and your landscape player stays rock-solid. No more black bars stealing the show; users get the seamless experience they expect. Dive in, tweak that prop, and swipe away worry-free.