Ответ 1
Вы можете попробовать настроить альфа-канал видеоизображения на 0 или закрыть 0.
Я прячу 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);
}
});
}
Вы можете попробовать настроить альфа-канал видеоизображения на 0 или закрыть 0.
Это может быть достигнуто одним из этих трюков
Вы можете установить высоту и ширину 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) {
}
Решено, что он делает свой макет невидимым, а не сам 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();
}
Гвоздь!