ViewPager2中页面不可见时如何自动停止正在播放的视频
ViewPager2滑动切换时视频自动停止播放实现方案
需求说明
应用通过API拉取视频列表,使用Adapter将视频加载到ViewPager2中播放,默认实现下滑动切换页面时,上一个页面的视频会继续在后台播放,需要实现仅当前用户停留的页面视频正常播放,滑动离开页面时对应视频自动停止的效果。
原始代码
VideoAdapter类代码
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); 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()); } }); }
实现方案
重写RecyclerView.Adapter的两个生命周期回调方法实现播放状态控制:
- 当页面挂载到窗口(用户切到当前页面)时,触发视频播放
- 当页面脱离窗口(用户切走当前页面)时,停止视频播放
同时调整SimpleExoPlayer的声明位置,统一管理播放实例状态。
修改后完整VideoAdapter代码
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); playerview.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL); simpleExoPlayer.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); simpleExoPlayer.addMediaItem(mediaItem); if(videoModel.getPlaying()!=null) { simpleExoPlayer.setPlayWhenReady(true); } else{ simpleExoPlayer.setPlayWhenReady(false); } simpleExoPlayer.prepare(); } } @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(); }
内容的提问来源于stack exchange,提问作者Chrizlove
相关产品推荐
相关产品推荐

