【问题标题】:How to communicate between recycler view Itemsrecycler view Items之间如何通信
【发布时间】:2021-03-06 14:08:05
【问题描述】:

我有一个回收站视图。每个项目视图持有者都有一个媒体播放器实例。所以基本上回收站视图显示视频项目的列表。 每当用户开始播放某个项目时,我都想停止当前正在播放的任何其他项目。

我想知道如何获取当前正在播放内容的视图的视图持有者实例,以便在开始播放新项目之前停止播放。

【问题讨论】:

  • 我想知道如何获取当前正在播放内容的视图的viewholder实例,其他内容在哪里?在同一个适配器或其他地方?
  • 根据需要保存最后点击的项目位置和代码
  • @Hemant Parmar 其他内容在同一个适配器中
  • @JyotiJK,请检查我提交的答案。它也在做同样的事情。

标签: android android-recyclerview


【解决方案1】:

只需使用媒体播放器的单个实例,当您开始播放视频时,只需检查媒体播放器是否正在播放,然后停止当前播放的视频并开始播放您想要的视频。

【讨论】:

    【解决方案2】:

    按照以下步骤进行

    1. 在适配器中取一个变量命名mCurrentPlayingPos = -1
    2. 在您开始播放视频时对点击或事件应用逻辑。如下所示

      if (mCurrentPlayingPos != -1) {
          // Find view holder using this position. If view holder is not null, then use method to release 
          // player as given mCurrentPlayingPos. 
          // If viewholder is null, that is recycled to no need to do anything. 
      } else {
          // This would be very first case    
          // Set value for mCurrentPlayingPos with positionInAdapter's value 
      }
      // Setup media player and play video below
      

    【讨论】:

      【解决方案3】:
      int sSelectedPos = 0;
      
      // call this on play button click 
      
           for (ModelMusic data : itemList) {
           if (itemList.indexOf(data) == position) {
            sSelectedPos = position;
           data.setPlaying(true);
           } else {
            data.setPlaying(false);
           }
            notifyDataSetChanged();
           }
      
      //POJO class to manage your play state of song.
          public class ModelMusic {
              private boolean isPlaying = false;
      
              public boolean isPlaying() {
                  return isPlaying;
              }
      
              public void setPlaying(boolean playing) {
                  isPlaying = playing;
              }
          }
      

      【讨论】:

      • 不,我不认为这会很好。虽然它会起作用,但刷新整个列表以进行单个项目更改是不好的。 ( notifyDataSetChanged();)
      • 如果没有 notifydatasetchanged,你将如何停止其他播放项目的操作。
      • 我不知道这是否是解决方案。但是我们可以使用 notifyItemChanged(int position) 吗?
      • @tamanneupane 你将如何限制用户在多行中只选择一项。如果您还没有解决这种类型的问题,那么您将无法了解这种方法。如果不改变 setplaying 实例,任何东西都不会反映到当前的 ui 视图中。
      • 是的,我理解你,但只有一个(对于第一次选择的项目)或两个(在第二个项目选择或以后)设置播放实例更改。你为什么要遍历整个列表?并进一步 notifyDataSetChanged();也在for循环里面。这是完全错误的
      【解决方案4】:

      您可以使用两个变量来存储以前的点击和最近的点击,

      int pre=-1,recent=-1;boolean clicked=false;
      

      在你的 onClick() 方法中,使用

      clicked=true;
      pre=recent;
      recent=clickedposition;
      if(pre!=-1)
      this.notifyItemChanged(pre);
      this.notifyItemChanged(recent);
      

      然后在你的 onBindViewHolder() 中添加这个

       if(clicked)
       { 
          if(pre!=-1 && pos==pre)
            stop(pre);//your code to stop the video
          if(pos==recent)
            {
                playvideo(recent);
                clicked=false;
            }
       }
      

      【讨论】:

        【解决方案5】:

        这是我的想法,试着去实现它; 为每个 recyclerView 项创建一个 state 属性 例如 isPlaying、isPaused

        public class Video {
           String url;
           boolean isPlaying;
        
           public void setPlaying(boolean isPlaying){
                  this.isPlaying = isPlaying;
           } 
        
           public boolean isPlaying(){
                  return isPlaying;
           }
        
        }
        

        当视频开始播放时设置 isPlaying 为 true

        public VideoAdapter extends RecyclerView.Adapter<VideoViewHolder>{
             Context ctx;
             List<Video> videos;
        
             public VideoAdapter(Context ctx, List<Videos> videos){
                   this.ctx = ctx;
                   this.videos = videos;
             }
        
              @Override
              public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        
                  View view = LayoutInflater.from(mContext).inflate(R.layout.video_view, parent, false);
                  VideoViewHolder holder = new VideoViewHolder(view);
                  return holder;
              }
        
              @Override
              public void onBindViewHolder(VideoViewHolder holder, int position) {
                  holder.bind(videos.get(position));
                  holder.setOnClickListener(this);
              }
        
              @Override
              public void onClick(View v) {
                    int adapterPosition = getAdapterPosition();
                    Video videos = video.get(adapterPosition)
        
                    if (video.isPlaying()) {
                        video.setPlaying(false);
                    } else {
                        video.setPlaying(true);
                    }
        
                    // Notify data set change will reload all view holders and play where playing is true, and cancel where cancel is false
                    notifyDataSetChanged();
                 }
          }
        
        
        
        
        class VideoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        VideoView videoView;
        
        VideoViewHolder(View itemView) {
            super(itemView);
            videoView = (VideoView) itemView.findViewById(R.id.videoView);
            itemView.setOnClickListener(this);
        }
        
        public void bind(Video video) {
            if (video.isPlaying()) {
                video.play();
            } else {
                videoView.stop();
            }
        }
        

        【讨论】:

        • 如果点击第 5 行时歌曲在第 1 位置和第 3 位置播放,您将如何停止播放?我已经发布了正确的一个。了解一下。
        【解决方案6】:

        https://github.com/arthur3486/ARVI 参考这个美丽的项目你会得到你的答案

        【讨论】:

          猜你喜欢
          • 2019-11-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-18
          相关资源
          最近更新 更多