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

时间:2014-01-24 12:47:30

标签: android video-streaming android-videoview

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

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >


<VideoView
        android:id="@+id/video"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:visibility="invisible" />

</RelativeLayout>

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);


            }
        });


}

4 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:4)

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

布局:

<FrameLayout
    android:id="@+id/layout_video_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <VideoView
        android:id="@+id/video_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="false"
        android:scrollbars="none"/>
</FrameLayout>

<ProgressBar
    android:id="@+id/progress"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:visibility="gone"
    />

设置OnPreparedListener:

videoView.setOnPreparedListener(this);

准备好之前显示进度条:

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

加载视频URI:

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

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

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

最后展示布局并开始播放视频:

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

@Override
public void startVideo() {
    videoView.start();
}

Nailed it!

答案 2 :(得分:3)

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

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

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

    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) {
    
    }
    

答案 3 :(得分:0)

更简单的解决方法:

只需为parentview添加虚假videoview,并为visiblity设置parentview,而不是更改visibility的{​​{1}}本身。