ViewPager 在 VideoView 之前在 Imageview 上显示 Mediacontrols
ViewPager showing Mediacontrols on Imageview ahead of VideoView
图库功能:
我正在开发一个类似于图库的功能,用户可以滑动查看他们上传的图片或视频。
问题:
只要在 imageview 之后有视频,videoview 的 Mediacontrols 就会在 imageview 上显示大约 2 秒
代码:
item_pager.xml :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@color/black_overlay"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/images_pager"
android:layout_width="match_parent"
android:layout_height="250dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:visibility="visible"
app:srcCompat="@drawable/cctv_icon" />
<VideoView
android:id="@+id/videoview"
android:layout_width="match_parent"
android:layout_height="250dp"
android:adjustViewBounds="true"
android:visibility="gone" />
</LinearLayout>
</layout>
PagerAdapter 代码:
public class ItemViewpager extends PagerAdapter implements MediaPlayer.OnPreparedListener,
View.OnClickListener, MediaPlayer.OnCompletionListener, View.OnFocusChangeListener {
private List<MediaInfo> mediaInfos;
private LayoutInflater layoutInflater;
private MediaController mediaController;
private HashMap<Integer, MediaController> mediaMap;
private VideoView videoView;
private ImageView imageView;
private int currPos = 0;
public ItemViewpager(List<MediaInfo> mediaInfos) {
this.mediaInfos = mediaInfos;
mediaMap = new HashMap<>(mediaInfos.size());
}
@Override
public int getCount() {
return mediaInfos.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == ((LinearLayout) object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
layoutInflater=
(LayoutInflater)container.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = layoutInflater.inflate(R.layout.item_pager, container, false);
imageView = itemView.findViewById(R.id.images_pager);
videoView = itemView.findViewById(R.id.videoview);
videoView.setOnPreparedListener(this);
videoView.setOnCompletionListener(this);
videoView.setOnFocusChangeListener(this);
boolean video = mediaInfos.get(position).video;
String uri = mediaInfos.get(position).uri;
mediaController = new MediaController(container.getContext());
mediaMap.put(position, mediaController);
if (video) {
imageView.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(Uri.parse(uri));
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.requestFocus();
videoView.seekTo(1);
} else {
imageView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.GONE);
Picasso.get().load(uri).fit().placeholder(R.mipmap.ic_launcher).into(imageView);
}
if (mediaMap.size() > 0)
mediaMap.get(position).hide();
container.addView(itemView);
return itemView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
}
public void onPageSelectionListener(int pos) {
currPos = pos;
boolean video = mediaInfos.get(currPos).video;
/*if (mediaMap.size() > 0) {
if (video)
mediaMap.get(currPos).show(0);
else
mediaMap.get(currPos).hide();
}*/
}
@Override
public void onClick(View view) {
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
boolean video = mediaInfos.get(currPos).video;
/*if (!video)
videoView.stopPlayback();
else
mediaMap.get(currPos).show();*/
}
@Override
public void onFocusChange(View view, boolean focus) {
}
}
提前致谢:
试试这个:
if (video) {
imageView.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(Uri.parse(uri));
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.requestFocus();
videoView.seekTo(1);
} else {
imageView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.GONE);
//add below line, hide mediaController
videoView.setMediaController(null);
Picasso.get().load(uri).fit().placeholder(R.mipmap.ic_launcher).into(imageView);
}
此代码隐藏 mediaController:
videoView.setMediaController(null);
试试下面的方法
boolean video = mediaInfos.get(currPos).video;
if(video){
mediaController.setVisibility(View.GONE);
// You need the object of mediaController which is of currently visible videoView on the screen
}else{
mediaController.setVisibility(View.VISIBLE);
}
首先创建mediacontroller的obj。需要显示时调用view.VISIBLE,需要隐藏时调用view.gone.
MediaController ctrl = new MediaController(context);
if(video){
ctrl.setVisibility(View.VISIBLE);
videoView.setMediaController(ctrl);
}else{
ctrl.setVisibility(View.GONE);
}
更好的选择是将您的 ViewPager
适配器 从 PagerAdapter
更改为 FragmentStatePagerAdapter
。这意味着您将不得不处理片段和生命周期。您必须将 VideoView/ImageView 放入 Fragment 中,并仅在用户看到 VideoView
时实例化视频播放。这就是您摆脱图像上显示 MediaController
的方法。您应该加载在片段内播放的视频的方法是这个:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
}
当标志 isVisibleToUser 为真时,您开始播放视频。
您可以在此处查看更多帮助:
Video is not pausing in fragment ViewPager
Google 有关更多详细信息,有大量示例如何实现您想要的。我也建议播放视频,你应该摆脱VideoView并学习如何使用ExoPlayer
播放视频,播放视频更复杂但是最后,它的优化和性能要好得多。
以后也尽量避免使用ViewPager,已经有基于RecyclerView的新组件ViewPager2
。
我的问题终于 解决了 answer Ronak Thakkar
使用的 CustomViewpager 曾尝试通过各种方式仅加载单个页面。
您总是可以在 class 中看到 源代码 。
图库功能:
我正在开发一个类似于图库的功能,用户可以滑动查看他们上传的图片或视频。
问题:
只要在 imageview 之后有视频,videoview 的 Mediacontrols 就会在 imageview 上显示大约 2 秒
代码:
item_pager.xml :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@color/black_overlay"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/images_pager"
android:layout_width="match_parent"
android:layout_height="250dp"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:visibility="visible"
app:srcCompat="@drawable/cctv_icon" />
<VideoView
android:id="@+id/videoview"
android:layout_width="match_parent"
android:layout_height="250dp"
android:adjustViewBounds="true"
android:visibility="gone" />
</LinearLayout>
</layout>
PagerAdapter 代码:
public class ItemViewpager extends PagerAdapter implements MediaPlayer.OnPreparedListener,
View.OnClickListener, MediaPlayer.OnCompletionListener, View.OnFocusChangeListener {
private List<MediaInfo> mediaInfos;
private LayoutInflater layoutInflater;
private MediaController mediaController;
private HashMap<Integer, MediaController> mediaMap;
private VideoView videoView;
private ImageView imageView;
private int currPos = 0;
public ItemViewpager(List<MediaInfo> mediaInfos) {
this.mediaInfos = mediaInfos;
mediaMap = new HashMap<>(mediaInfos.size());
}
@Override
public int getCount() {
return mediaInfos.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == ((LinearLayout) object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
layoutInflater=
(LayoutInflater)container.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = layoutInflater.inflate(R.layout.item_pager, container, false);
imageView = itemView.findViewById(R.id.images_pager);
videoView = itemView.findViewById(R.id.videoview);
videoView.setOnPreparedListener(this);
videoView.setOnCompletionListener(this);
videoView.setOnFocusChangeListener(this);
boolean video = mediaInfos.get(position).video;
String uri = mediaInfos.get(position).uri;
mediaController = new MediaController(container.getContext());
mediaMap.put(position, mediaController);
if (video) {
imageView.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(Uri.parse(uri));
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.requestFocus();
videoView.seekTo(1);
} else {
imageView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.GONE);
Picasso.get().load(uri).fit().placeholder(R.mipmap.ic_launcher).into(imageView);
}
if (mediaMap.size() > 0)
mediaMap.get(position).hide();
container.addView(itemView);
return itemView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
}
public void onPageSelectionListener(int pos) {
currPos = pos;
boolean video = mediaInfos.get(currPos).video;
/*if (mediaMap.size() > 0) {
if (video)
mediaMap.get(currPos).show(0);
else
mediaMap.get(currPos).hide();
}*/
}
@Override
public void onClick(View view) {
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
boolean video = mediaInfos.get(currPos).video;
/*if (!video)
videoView.stopPlayback();
else
mediaMap.get(currPos).show();*/
}
@Override
public void onFocusChange(View view, boolean focus) {
}
}
提前致谢:
试试这个:
if (video) {
imageView.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
videoView.setVideoURI(Uri.parse(uri));
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.requestFocus();
videoView.seekTo(1);
} else {
imageView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.GONE);
//add below line, hide mediaController
videoView.setMediaController(null);
Picasso.get().load(uri).fit().placeholder(R.mipmap.ic_launcher).into(imageView);
}
此代码隐藏 mediaController:
videoView.setMediaController(null);
试试下面的方法
boolean video = mediaInfos.get(currPos).video;
if(video){
mediaController.setVisibility(View.GONE);
// You need the object of mediaController which is of currently visible videoView on the screen
}else{
mediaController.setVisibility(View.VISIBLE);
}
首先创建mediacontroller的obj。需要显示时调用view.VISIBLE,需要隐藏时调用view.gone.
MediaController ctrl = new MediaController(context);
if(video){
ctrl.setVisibility(View.VISIBLE);
videoView.setMediaController(ctrl);
}else{
ctrl.setVisibility(View.GONE);
}
更好的选择是将您的 ViewPager
适配器 从 PagerAdapter
更改为 FragmentStatePagerAdapter
。这意味着您将不得不处理片段和生命周期。您必须将 VideoView/ImageView 放入 Fragment 中,并仅在用户看到 VideoView
时实例化视频播放。这就是您摆脱图像上显示 MediaController
的方法。您应该加载在片段内播放的视频的方法是这个:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
}
当标志 isVisibleToUser 为真时,您开始播放视频。 您可以在此处查看更多帮助: Video is not pausing in fragment ViewPager
Google 有关更多详细信息,有大量示例如何实现您想要的。我也建议播放视频,你应该摆脱VideoView并学习如何使用ExoPlayer
播放视频,播放视频更复杂但是最后,它的优化和性能要好得多。
以后也尽量避免使用ViewPager,已经有基于RecyclerView的新组件ViewPager2
。
我的问题终于 解决了 answer Ronak Thakkar
使用的 CustomViewpager 曾尝试通过各种方式仅加载单个页面。
您总是可以在 class 中看到 源代码 。