Fragment中VideoView仅显示黑屏求助(需静音及重播功能)
Fixing VideoView Black Screen in Fragment (Muted + Auto-Replay)
Hey there! Let's get that VideoView working properly in your Fragment—no black screens, muted playback, and auto-replay included. I'll break down the common issues and share a tested solution based on your requirements.
First, Let's Check Your Layout
Make sure your Layout.xml has a properly configured VideoView. If it's set to wrap_content for width/height, it might show a black screen before the video loads. Here's a solid base layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <VideoView android:id="@+id/videoView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" /> </FrameLayout>
Common Causes of Black Screen
Before jumping to fixed code, let's rule out quick fixes:
- Unsupported Video Format: Android natively supports MP4 (H.264/H.265), 3GP, and WebM. Convert your video if it's in another format.
- Incorrect Video Path: Double-check if your video is in the right location (e.g.,
res/rawfolder with lowercase, no special characters) or if the URL/local file path is valid. - Missing Permissions: For network videos, add
<uses-permission android:name="android.permission.INTERNET" />to yourAndroidManifest.xml. For local storage videos, add the appropriate read permissions. - Hardware Acceleration: Some devices require hardware acceleration for video playback. Add
android:hardwareAccelerated="true"to your<application>or<activity>tag in the manifest.
Fixed Fragment Code (Muted + Auto-Replay)
This code handles Fragment lifecycle correctly, ensures the video is ready before playing, mutes audio, and auto-replays when finished:
Kotlin Version
import android.net.Uri import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.VideoView import androidx.fragment.app.Fragment class VideoFragment : Fragment() { private lateinit var videoView: VideoView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.your_fragment_layout, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) videoView = view.findViewById(R.id.videoView) // Replace with your video source: raw resource, local file, or network URL val videoUri = Uri.parse("android.resource://${requireContext().packageName}/${R.raw.your_video_file}") videoView.setVideoURI(videoUri) // Handle video preparation: mute and start playback videoView.setOnPreparedListener { mediaPlayer -> // Mute audio mediaPlayer.setVolume(0f, 0f) // Enable auto-replay (two options: use isLooping or OnCompletionListener) mediaPlayer.isLooping = true // Start playing once ready videoView.start() } // Alternative auto-replay method (if you need custom logic on completion) /* videoView.setOnCompletionListener { videoView.seekTo(0) videoView.start() } */ } // Manage playback across Fragment lifecycle to avoid leaks override fun onPause() { super.onPause() videoView.pause() } override fun onResume() { super.onResume() if (!videoView.isPlaying) { videoView.start() } } override fun onDestroyView() { super.onDestroyView() videoView.stopPlayback() // Release video resources } }
Java Version
import android.net.Uri; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.VideoView; import androidx.fragment.app.Fragment; public class VideoFragment extends Fragment { private VideoView videoView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.your_fragment_layout, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); videoView = view.findViewById(R.id.videoView); // Replace with your video source Uri videoUri = Uri.parse("android.resource://" + requireContext().getPackageName() + "/" + R.raw.your_video_file); videoView.setVideoURI(videoUri); videoView.setOnPreparedListener(mediaPlayer -> { // Mute audio mediaPlayer.setVolume(0f, 0f); // Enable auto-replay mediaPlayer.setLooping(true); // Start playback videoView.start(); }); // Alternative auto-replay /* videoView.setOnCompletionListener(mp -> { videoView.seekTo(0); videoView.start(); }); */ } @Override public void onPause() { super.onPause(); videoView.pause(); } @Override public void onResume() { super.onResume(); if (!videoView.isPlaying()) { videoView.start(); } } @Override public void onDestroyView() { super.onDestroyView(); videoView.stopPlayback(); } }
Why This Works
- Lifecycle Handling: Initializing VideoView in
onViewCreatedensures the Fragment's view is fully inflated before accessing the widget. Pausing/resuming playback prevents background audio leaks. - Prepared Listener: We wait for the video to be ready before starting playback, which avoids black screens caused by trying to play an unloaded video.
- Mute & Replay: Using
setVolume(0f,0f)mutes the audio, and eithersetLooping(true)or anOnCompletionListenerhandles auto-replay.
内容的提问来源于stack exchange,提问作者user9313301
相关产品推荐
相关产品推荐

