当页面在 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();
}
}
您可以覆盖 onViewAttachedToWindow
、onViewDetachedFromWindow
和 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
}
我有一个应用程序,我可以在其中进行 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 我已经解决了这个问题
这是解决
后更新的Adapterclasspublic 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();
}
}
您可以覆盖 onViewAttachedToWindow
、onViewDetachedFromWindow
和 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
}