VideoView onPrepared не вызывается, если 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);


            }
        });


}

Ответы

Ответ 1

Вы можете попробовать настроить альфа-канал видеоизображения на 0 или закрыть 0.

Ответ 2

Это может быть достигнуто одним из этих трюков

  • Вы можете установить высоту и ширину VideoView на 1px до тех пор, пока видео не будет подготовлено, а затем переключитесь на полноэкранный режим, изменив свойства на match parent

  • Как сказал @FDIM в своем ответе, мы можем установить альфа-значение представления в 0 до тех пор, пока видео не будет подготовлено. Но он работает, только если мы используем TextureView для загрузки видео. Он не работает с обычным VideoView. Вот пользовательский VideoView, расширяющий TextureView, который имитирует реализацию по умолчанию VideoVideo. Этот класс можно напрямую использовать в XML файле и может установить альфа-значение в 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

Решено, что он делает свой макет невидимым, а не сам 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();
}

Гвоздь!