ViewPager2 仅在所选项目中播放视频
ViewPager2 play video only in selected item
我有一个 ViewPager2
带有填充和页面转换器。在 viewpager 中,我使用 TextureView
托管片段来播放视频。问题是每个可见的 TextureView 都开始播放它的视频。我试图覆盖片段的 onPause()
和 OnStart()
方法以从那里调用 mediaPlayer.start()
和 mediaPlayer.stop()
。这样只会播放所选片段的视频。但是,当我在 viewpager 中向后移动时,已经开始的视频将不会再次开始。有时它甚至没有被加载,只有一个空的 TextureView 是可见的。
这是片段的代码:
public TextureView mTextureView;
public MediaPlayer mMediaPlayer;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_video_player,container,false);
VideoSingleton videos = VideoSingleton.get(getContext());
mVideo = videos.getVideoWithTitle(getArguments().getString(KEY_VIDEO));
mTextureView = view.findViewById(R.id.video_texture_view);
mMediaPlayer= new MediaPlayer();
try {
mMediaPlayer.setDataSource(getContext(),mVideo.getVideoUri());
} catch (IOException e) {
e.printStackTrace();
}
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
Surface s = new Surface(surfaceTexture);
try {
mMediaPlayer.setSurface(s);
mMediaPlayer.prepare();
} catch (IllegalArgumentException | SecurityException | IllegalStateException | IOException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
});
return view;
}
@Override
public void onPause() {
super.onPause();
mMediaPlayer.stop();
}
@Override
public void onResume() {
super.onResume();
mMediaPlayer.start();
}
这是我设置 viewpager 的方式:
mViewPager = findViewById(R.id.video_player_viewPager);
final ScreenSlidePagerAdapter slidePagerAdapter = new ScreenSlidePagerAdapter(this);
mViewPager.setAdapter(slidePagerAdapter);
mViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
mViewPager.setOffscreenPageLimit(1);
mViewPager.setPadding(90, 20, 90, 20);
mViewPager.setPageTransformer(new ZoomOutPageTransformer());
mViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
mTitleTextView.setText(mDataBase.get(position).getTitle());
}
});
ScreenSlideAdapter:
private class ScreenSlidePagerAdapter extends FragmentStateAdapter {
public ScreenSlidePagerAdapter(FragmentActivity fa) {
super(fa);
}
@Override
public Fragment createFragment(int position) {
Video video = mDataBase.get(position);
return VideoPlayerFragment.newInstance(video.getTitle());
}
@Override
public int getItemCount() {
return mDataBase.size();
}
}
ZoomOutPageTransformer 来自 here
这是activity里面的viewpager XML:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="@color/colorPrimaryDark">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/video_player_viewPager"
android:clipToPadding="false"
android:clipChildren="false"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
这是片段的布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginLeft="@dimen/pageMarginAndOffset"
android:layout_marginRight="@dimen/pageMarginAndOffset"
android:layout_height="match_parent"
app:cardCornerRadius="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextureView
android:id="@+id/video_texture_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
如何在 viewpager 中只播放所选项目的视频?
在Fragment#setMenuVisibility
中播放和暂停视频播放器:
@Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
if (player != null) {
player.setPlayWhenReady(menuVisible);
}
}
我有一个 ViewPager2
带有填充和页面转换器。在 viewpager 中,我使用 TextureView
托管片段来播放视频。问题是每个可见的 TextureView 都开始播放它的视频。我试图覆盖片段的 onPause()
和 OnStart()
方法以从那里调用 mediaPlayer.start()
和 mediaPlayer.stop()
。这样只会播放所选片段的视频。但是,当我在 viewpager 中向后移动时,已经开始的视频将不会再次开始。有时它甚至没有被加载,只有一个空的 TextureView 是可见的。
这是片段的代码:
public TextureView mTextureView;
public MediaPlayer mMediaPlayer;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_video_player,container,false);
VideoSingleton videos = VideoSingleton.get(getContext());
mVideo = videos.getVideoWithTitle(getArguments().getString(KEY_VIDEO));
mTextureView = view.findViewById(R.id.video_texture_view);
mMediaPlayer= new MediaPlayer();
try {
mMediaPlayer.setDataSource(getContext(),mVideo.getVideoUri());
} catch (IOException e) {
e.printStackTrace();
}
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
Surface s = new Surface(surfaceTexture);
try {
mMediaPlayer.setSurface(s);
mMediaPlayer.prepare();
} catch (IllegalArgumentException | SecurityException | IllegalStateException | IOException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
});
return view;
}
@Override
public void onPause() {
super.onPause();
mMediaPlayer.stop();
}
@Override
public void onResume() {
super.onResume();
mMediaPlayer.start();
}
这是我设置 viewpager 的方式:
mViewPager = findViewById(R.id.video_player_viewPager);
final ScreenSlidePagerAdapter slidePagerAdapter = new ScreenSlidePagerAdapter(this);
mViewPager.setAdapter(slidePagerAdapter);
mViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
mViewPager.setOffscreenPageLimit(1);
mViewPager.setPadding(90, 20, 90, 20);
mViewPager.setPageTransformer(new ZoomOutPageTransformer());
mViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
mTitleTextView.setText(mDataBase.get(position).getTitle());
}
});
ScreenSlideAdapter:
private class ScreenSlidePagerAdapter extends FragmentStateAdapter {
public ScreenSlidePagerAdapter(FragmentActivity fa) {
super(fa);
}
@Override
public Fragment createFragment(int position) {
Video video = mDataBase.get(position);
return VideoPlayerFragment.newInstance(video.getTitle());
}
@Override
public int getItemCount() {
return mDataBase.size();
}
}
ZoomOutPageTransformer 来自 here
这是activity里面的viewpager XML:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="@color/colorPrimaryDark">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/video_player_viewPager"
android:clipToPadding="false"
android:clipChildren="false"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
这是片段的布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginLeft="@dimen/pageMarginAndOffset"
android:layout_marginRight="@dimen/pageMarginAndOffset"
android:layout_height="match_parent"
app:cardCornerRadius="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextureView
android:id="@+id/video_texture_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
如何在 viewpager 中只播放所选项目的视频?
在Fragment#setMenuVisibility
中播放和暂停视频播放器:
@Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
if (player != null) {
player.setPlayWhenReady(menuVisible);
}
}