我已经实现了一个recyclerview,我在其中添加纹理视图作为列表项来播放来自url的视频.现在像藤蔓和Instagram应用程序我想播放视频,当它在recyclerview中可见,并在listitem离开屏幕时停止/暂停视频.以下是我的代码:
VideosAdapter类:
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类:
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,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,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 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; }
}
为了实现这一点,我得到了this线程中讨论的可见项目位置.但我不知道如何将可见滚动位置传递给我的VideoPlayController类以及如何根据滚动位置跟踪和访问正确的对象.