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 中看到 源代码