Play / Pause video when listitem becomes visible in recyclerview

I implemented recyclerview in which I add texture views as list items to play videos from a URL. Now, as an application for the vine and instagram, I want to play the video when it is visible in recycliewiew mode and stop / pause the video when the listitem exits the screen. Below is my code:

Adapter video class:

public class VideosAdapter extends RecyclerView.Adapter<VideosAdapter.ViewHolder> { private static String TAG = "VideosAdapter"; Context context; private ArrayList<String> urls; RecyclerView recyclerView; public static class ViewHolder extends RecyclerView.ViewHolder { public TextureView textureView; public TextView textView; public ViewHolder(View v) { super(v); textureView = (TextureView) v.findViewById(R.id.textureView); textView = (TextView) v.findViewById(R.id.textView); } } public VideosAdapter(Context context, RecyclerView recyclerView, final ArrayList<String> urls) { this.context = context; this.recyclerView = recyclerView; this.urls = urls; recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if(newState == RecyclerView.SCROLL_STATE_IDLE) { LinearLayoutManager layoutManager = ((LinearLayoutManager) recyclerView.getLayoutManager()); int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition(); int findFirstCompletelyVisibleItemPosition = layoutManager.findFirstCompletelyVisibleItemPosition(); int findLastVisibleItemPosition = layoutManager.findLastVisibleItemPosition(); int findLastCompletelyVisibleItemPosition = layoutManager.findLastCompletelyVisibleItemPosition(); *//*Log.i(TAG, "firstVisiblePosition = " + String.valueOf(firstVisiblePosition)); Log.i(TAG, "findFirstCompletelyVisibleItemPosition = " + String.valueOf(findFirstCompletelyVisibleItemPosition)); Log.i(TAG, "findLastVisibleItemPosition = " + String.valueOf(findLastVisibleItemPosition)); Log.i(TAG, "findLastCompletelyVisibleItemPosition = " + String.valueOf(findLastCompletelyVisibleItemPosition));*//* Log.i(TAG, "//////////////////////////////////////////////////////////////"); if(findFirstCompletelyVisibleItemPosition>=0) { Log.i(TAG, "Playing_URl = " + urls.get(findFirstCompletelyVisibleItemPosition)); int tempPreviousUrl = findFirstCompletelyVisibleItemPosition - 1; if(tempPreviousUrl>=0) Log.i(TAG, "Stop_Playing_URl = " + urls.get(tempPreviousUrl)); } else { Log.i(TAG, "Playing_URl = " + urls.get(firstVisiblePosition)); int tempPreviousUrl = firstVisiblePosition - 1; if(tempPreviousUrl>=0) Log.i(TAG, "Stop_Playing_URl = " + urls.get(tempPreviousUrl)); } } } }); } // Create new views (invoked by the layout manager) @Override public VideosAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_main, parent, false); ViewHolder viewHolder = new ViewHolder(v); return viewHolder; } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder holder, int position) { String url = urls.get(position); holder.textView.setText(url); //Log.i("BindViewHolderCalledFor", position + " = " + url); VideoPlayController videoPlayController = new VideoPlayController(context, recyclerView, holder.textureView, url); if(position==0) { videoPlayController.loadVideo(); } } @Override public int getItemCount() { return urls.size(); } 

}

VideoPlayController Class:

 public class VideoPlayController implements TextureView.SurfaceTextureListener { private static String TAG = "VideoPlayController"; Context context; String url; MediaPlayer mp; Surface surface; SurfaceTexture s; RecyclerView recyclerView; TextureView textureView; public VideoPlayController(Context context, RecyclerView recyclerView, TextureView textureView, final String url) { this.context = context; this.recyclerView = recyclerView; this.textureView = textureView; this.url = url; recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if(newState == RecyclerView.SCROLL_STATE_IDLE) { Log.i(TAG, "OnScrollStateChangedCalled For: " + url); //When scroll is at idol position check if item is visible } } }); } public void loadVideo() { textureView.setSurfaceTextureListener(this); } @Override public void onSurfaceTextureAvailable(final SurfaceTexture surface, int width, int height) { Log.d("surface_available-url", this.url); startVideo(surface); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { Log.d("surface_destroyed-url", this.url); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { Log.d("surface_destroyed-url", this.url); this.mp.stop(); this.mp.reset(); this.mp.release(); this.mp = null; return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } public void startVideo(SurfaceTexture t) { this.surface = new Surface(t); this.mp = new MediaPlayer(); this.mp.setSurface(this.surface); try { Uri uri = Uri.parse(this.url); this.mp.setDataSource(url); this.mp.prepareAsync(); this.mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { mp.setLooping(true); mp.start(); } }); } catch (IllegalArgumentException e1) { e1.printStackTrace(); } catch (SecurityException e1) { e1.printStackTrace(); } catch (IllegalStateException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } try { } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } try { } catch (IllegalStateException e) { e.printStackTrace(); } } public void changePlayState() { if(this.mp.isPlaying()) this.mp.stop(); else this.mp.start(); } public static boolean isViewVisible(View subView, View parentView) { Rect scrollBounds = new Rect(); parentView.getHitRect(scrollBounds); if (subView.getLocalVisibleRect(scrollBounds)) { return true; } return false; } 

}

To achieve this, I get visible position positions, as discussed in this thread. But I don’t know how to pass the visible scroll position to my VideoPlayController class and how to track and access an object based on the scroll position.

+6
source share

Source: https://habr.com/ru/post/989735/


All Articles