如果VideoView不可见,则不会调用VideoView onPrepared

我最初隐藏了VideoView ,当video加载时,我正在显示VideoView 。 但是如果最初invisible VideoView就不会调用onPrepared 。 但是,如果VideoView可见,则会正确调用onPrepared 。 有没有办法隐藏videoView直到加载video。 任何帮助,将不胜感激。 谢谢!

activity_main.xml中

    

MainActivity.java

 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); VideoView videoView = (VideoView) findViewById(R.id.video); Uri videoUri = Uri.parse(url); videoView.setVideoURI(videoUri); videoView.requestFocus(); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { Toast.makeText(mActivity, "on prepared", Toast.LENGTH_SHORT).show(); videoView.setVisibility(View.VISIBLE); } }); } 

您可以尝试将video视图的Alpha通道设置为0或接近0。

解决了它使其布局不可见而不是videoView本身。 感谢@ J.Kowalski。

布局:

     

设置OnPreparedListener:

 videoView.setOnPreparedListener(this); 

准备好之前显示进度条:

 @Override public void showProgress() { progress.setVisibility(View.VISIBLE); layoutVideoView.setVisibility(View.INVISIBLE); } 

加载videoURI:

 @Override public void loadVideo(Uri uri) { videoView.setVideoURI(uri); } 

当它准备就绪时,onPrepared被称为:

 @Override public void onPrepared(MediaPlayer mp) { Log.d("debug", "onPrepared"); iStepPreviewPresenter.onVideoViewReady(); } 

最后展示布局和开始video:

 @Override public void hideProgress() { progress.setVisibility(View.INVISIBLE); layoutVideoView.setVisibility(View.VISIBLE); } @Override public void startVideo() { videoView.start(); } 

搞定了!

它可以通过其中一种技巧来实现

  1. 您可以将VideoView的高度和宽度设置为1px直到video准备好,然后通过更改属性以match parent切换到全屏

  2. 正如@FDIM在他的回答中所说,我们可以将视图的alpha值设置为0,直到准备好video。 但它只有在我们使用TextureView加载video时才有效。 它不适用于普通的VideoView 。 这是一个自定义VideoView扩展TextureView ,它模仿默认的VideoVideo实现。 此类可以直接在xml文件中使用,并可以将alpha设置为0以隐藏video。

     public class TextureVideoView extends TextureView implements SurfaceTextureListener { private MediaPlayer mMediaPlayer; public TextureVideoView(Context context) { super(context); init(); } public TextureVideoView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { mMediaPlayer = new MediaPlayer(); this.setSurfaceTextureListener(this); } public void seekTo(int msec) { mMediaPlayer.seekTo(msec); } public void setVideoPath(final String path) throws IOException { mMediaPlayer.reset(); mMediaPlayer.setDataSource(path); mMediaPlayer.prepare(); } public void setVideoPath(FileDescriptor fd, long offset, long length) throws IOException { mMediaPlayer.reset(); mMediaPlayer.setDataSource(fd, offset, length); mMediaPlayer.prepare(); } public void setVideoURI(Context context, Uri uri) throws IOException { mMediaPlayer.reset(); mMediaPlayer.setDataSource(context, uri); } public void setOnPreparedListener(OnPreparedListener onPreparedListener) { mMediaPlayer.setOnPreparedListener(onPreparedListener); } public void setOnCompletionListener(OnCompletionListener onCompletionListener) { mMediaPlayer.setOnCompletionListener(onCompletionListener); } public void setOnErrorListener(OnErrorListener onErrorListener) { mMediaPlayer.setOnErrorListener(onErrorListener); } public void start() { mMediaPlayer.start(); } public void pause() { mMediaPlayer.pause(); } public void setVolume(float leftVolume, float rightVolume ) { mMediaPlayer.setVolume(leftVolume, rightVolume); } public boolean isPlaying() { return mMediaPlayer.isPlaying(); } public void stopPlayback() { mMediaPlayer.stop(); } public void reset() { mMediaPlayer.reset(); } public void release() { mMediaPlayer.release(); } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { mMediaPlayer.setSurface(new Surface(surface)); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false; } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } 

更简单的解决方法:

只需为videoview添加虚拟parentview ,并videoview设置visibility ,而不是更改videoview本身的visibility