You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 21:09:00