当页面在 ViewPager2 中不可见时如何停止视频

How to stop a video when the page is not visible in ViewPager2

我有一个应用程序,我可以在其中进行 API 调用并获取视频数组列表,我使用适配器在 viewpager 中播放这些视频。当我滚动 viewpager 时,之前播放的视频仍然继续播放,甚至在我再次滚动之后。 我想要它,以便仅当用户在该特定 viewpager 视图上时才播放视频,并且当用户滚动时视频应该停止。

VideoAdapter 代码class

public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoViewHolder> {

ArrayList<VideoModel> videos;

public VideoAdapter(ArrayList<VideoModel> videos) {
    this.videos = videos;
}

@NonNull
@Override
public VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_lyt,parent,false);
    return new VideoViewHolder(view);

}

@Override
public void onBindViewHolder(@NonNull VideoViewHolder holder, int position) {
holder.setData(videos.get(position));
}

@Override
public int getItemCount() {
    return videos.size();
}

class VideoViewHolder extends RecyclerView.ViewHolder {

    PlayerView playerview;
    TextView title,desc;
    SimpleExoPlayer simpleExoPlayer;

    public VideoViewHolder(@NonNull View itemView) {
        super(itemView);

        playerview = itemView.findViewById(R.id.playerView);
        title = itemView.findViewById(R.id.titleTextView);
        desc = itemView.findViewById(R.id.descTextView);
    }
    void setData(VideoModel videoModel)
    {
        Log.d("setting","data");
        simpleExoPlayer = new SimpleExoPlayer.Builder(itemView.getContext()).build();
        playerview.setPlayer(simpleExoPlayer);
        title.setText(videoModel.getUser_info().getTitle());
        desc.setText(videoModel.getDesc());
        MediaItem mediaItem = MediaItem.fromUri(videoModel.getUrl());
        simpleExoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);
        playerview.setUseController(false);
        //making the video fit the entire screen
        playerview.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
        simpleExoPlayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
        simpleExoPlayer.addMediaItem(mediaItem);
        simpleExoPlayer.setPlayWhenReady(false);
        simpleExoPlayer.prepare();
    }
}

MainActivity 的代码

public class MainActivity extends AppCompatActivity {

ViewPager2 viewPager2;
ArrayList<VideoModel> videos, videosSend;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
    viewPager2 = (ViewPager2) findViewById(R.id.viewpagerVideos);
    videos = new ArrayList<>();
    videosSend = new ArrayList<>();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("myapi")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    APICall apiCall = retrofit.create(APICall.class);
    Call<VideoAPIData> call = apiCall.getVideos();
    call.enqueue(new Callback<VideoAPIData>() {
        @Override
        public void onResponse(Call<VideoAPIData> call, Response<VideoAPIData> response) {
            videos = response.body().getMsg();
            Log.d("API","Success");
            viewPager2.setAdapter(new VideoAdapter(videos));
        }
        @Override
        public void onFailure(Call<VideoAPIData> call, Throwable t) {
            Log.d("API Fail", t.getMessage());
        }
    });
}

感谢 Nitish Chaudhary 我已经解决了这个问题

这是解决

后更新的Adapterclass
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoViewHolder> {

ArrayList<VideoModel> videos;
SimpleExoPlayer simpleExoPlayer;

public VideoAdapter(ArrayList<VideoModel> videos) {
    this.videos = videos;
}

@NonNull
@Override
public VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_lyt,parent,false);
    return new VideoViewHolder(view);

}

@Override
public void onBindViewHolder(@NonNull VideoViewHolder holder, int position) {
holder.setData(videos.get(position));
}

@Override
public int getItemCount() {
    return videos.size();
}

class VideoViewHolder extends RecyclerView.ViewHolder {

    PlayerView playerview;
    TextView title,desc;

    public VideoViewHolder(@NonNull View itemView) {
        super(itemView);

        playerview = itemView.findViewById(R.id.playerView);
        title = itemView.findViewById(R.id.titleTextView);
        desc = itemView.findViewById(R.id.descTextView);
    }
    void setData(VideoModel videoModel)
    {
        simpleExoPlayer = new SimpleExoPlayer.Builder(itemView.getContext()).build();
        playerview.setPlayer(simpleExoPlayer);
        title.setText(videoModel.getUser_info().getTitle());
        desc.setText(videoModel.getDesc());
        MediaItem mediaItem = MediaItem.fromUri(videoModel.getUrl());
        simpleExoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);
        playerview.setUseController(false);
        //making the video fit the entire screen
        playerview.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
        simpleExoPlayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
        simpleExoPlayer.addMediaItem(mediaItem);
        
         //this code sets the playwhenready(true) for only the first video to be shown at the launch of app
        if(videoModel.getPlaying()!=null)
        {
            simpleExoPlayer.setPlayWhenReady(true);
        }
        else{
            simpleExoPlayer.setPlayWhenReady(false);
        }
        simpleExoPlayer.prepare();
    }
}

//this is the change that solves this issue

@Override
public void onViewAttachedToWindow(@NonNull VideoViewHolder holder) {
    super.onViewAttachedToWindow(holder);
    holder.playerview.getPlayer().setPlayWhenReady(true);
    holder.playerview.getPlayer().prepare();
}

@Override
public void onViewDetachedFromWindow(@NonNull VideoViewHolder holder) {
    super.onViewDetachedFromWindow(holder);
    holder.playerview.getPlayer().setPlayWhenReady(false);
    holder.playerview.getPlayer().stop();
}

}

您可以覆盖 onViewAttachedToWindowonViewDetachedFromWindow 和 play/pause 您的视频,仅当用户可见时。

回收器适配器

public class VideoAdapter extends RecyclerView.Adapter {

@Override
@Override
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
    super.onViewAttachedToWindow(holder);
    //play video


}

@Override
public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
    super.onViewDetachedFromWindow(holder);
    //pause video

 
}