I have an ExoPlayer
instance within a RecyclerView
in my Android app. While the player works perfectly with the next and previous buttons, I’m facing an issue where the videos don’t switch correctly when I swipe left or right on the RecyclerView
. Instead, I just see a blank space where the next or previous video should be and audio of previous video.
RecyclerView class
public class Onclick_MediaViewer extends Fragment {
int pos;
ArrayList<String> galleryItems;
PlayerView video;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
galleryItems = new ArrayList<>();
return inflater.inflate(R.layout.onclick_mediaviewer,container,false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RecyclerView recyclerView = view.findViewById(R.id.mediaViewerRecycler);
layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
SnapHelper snapHelper = new PagerSnapHelper();
recyclerView.setLayoutManager(layoutManager);
snapHelper.attachToRecyclerView(recyclerView);
recyclerView.addItemDecoration(new LinePagerIndicatorDecoration());
Media_OnclickAdapter adapter = new Media_OnclickAdapter();
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE){
//Handle new video
int pos = layoutManager.findFirstCompletelyVisibleItemPosition();
// I can see update on position here which i can use to switch video
Log.d(TAG, "onScrollStateChanged: "+pos);
}
}
});
}
private class Media_OnclickAdapter extends RecyclerView.Adapter<Media_OnclickAdapter.Viewholder>{
@NonNull
@Override
public Viewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.onclick_mediaviewer_video,parent,false);
return new Viewholder(view);
}
@Override
public void onBindViewHolder(@NonNull Viewholder holder, int position) {
Log.d(TAG,"Type == "+holder.getItemViewType());
pos = holder.getAbsoluteAdapterPosition();
ExoplayerSingle_Instance.getInstance()
.prepareExoPlayer(getActivity(),video,galleryItems);
}
@Override
public int getItemCount() {
return galleryItems.size();
}
private class Viewholder extends RecyclerView.ViewHolder {
public Viewholder(@NonNull View itemView) {
super(itemView);
video = itemView.findViewById(R.id.onclickMediaViewer_Video);
}
}
}
}
Exoplayer Single Instance Class
public class ExoplayerSingle_Instance {
private static final String TAG = "### Exoplayer ###";
private static ExoplayerSingle_Instance instance;
private ExoPlayer player;
private boolean isPlayerPlaying;
private ExoplayerSingle_Instance() {
}
public static synchronized ExoplayerSingle_Instance getInstance() {
if (instance == null) {
instance = new ExoplayerSingle_Instance();
}
return instance;
}
public void prepareExoPlayer(Context context, PlayerView exoPlayerView, ArrayList<String> videoUri) {
if (context == null || exoPlayerView == null) {
return;
}
if (player == null) {
player = new ExoPlayer.Builder(context).build();
}
exoPlayerView.setPlayer(player);
player.clearMediaItems();
List<MediaItem> mediaItem = new ArrayList<>();
for (String s: videoUri){
mediaItem.add(MediaItem.fromUri(s));
}
player.setMediaItems(mediaItem);
player.prepare();
player.play();
}
public void stopPlayback() {
if (player != null) {
player.setPlayWhenReady(false);
player.stop(); // Reset the player without releasing it
}
}
public void goToBackground() {
if (player != null) {
isPlayerPlaying = player.getPlayWhenReady();
player.setPlayWhenReady(false);
}
}
public void goToForeground() {
if (player != null) {
player.setPlayWhenReady(isPlayerPlaying);
}
}
public void releaseVideoPlayer() {
if (player != null) {
player.release();
}
player = null;
}
}