title: Play Video in RecyclerView - Play/Pause video when scrolled off screen
body: <p>I've implemented a Recycler view of video players implemented using a texture view and media player.  </p>
  
  <p>If I scroll down through the list I can click on the item and the video plays.  However, with the recycler view once the view goes off screen it is then recycled for reuse.  If I scroll back up all the views are now blank (black).</p>
  
  <p>I am looking to add functionality that when the user scrolls the video off screen that it will pause and keep reference to that video so that if they scroll back to that video it will play from that point.</p>
  
  <p>I have checked <a href="https://stackoverflow.com/questions/30978030/playing-video-using-textureview-in-recyclerview">this</a> out however I don't want to download the video, I just want to stream.  I am not looking for someone to do this for me, I'm just looking for some pointers and hoping someone could share their knowledge on this...
  Thanks in advance  </p>
  
  <p>This is what I have done so far:</p>
  
  <p><strong>VIDEO PLAYER</strong> </p>
  
  <pre><code>public class CustomVideoPlayer implements TextureView.SurfaceTextureListener, VideoControllerView.MediaPlayerControl, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener {
  
      private Context mContext;
      private String mUrl;
      private MediaPlayer mMediaPlayer;
      private Surface mSurface;
      private VideoControllerView mControllerView;
  
      private TextureView mTextureView;
      private CardView mCardView;
      private ProgressBar mProgress;
      private FrameLayout mView;
      private RelativeLayout mLayout;
  
  
      public CustomVideoPlayer(Context ctx, TextureView view, ProgressBar progressDialog, FrameLayout holderView){
  
          this.mContext = ctx;
          mTextureView = view;
          mTextureView.setSurfaceTextureListener(this);
          mProgress = progressDialog;
          mControllerView = new VideoControllerView(ctx);
          mView = holderView;
  
          mTextureView.setOnTouchListener(new ControlTouchListener());
      }
  
  
      @Override
      public boolean canPause() {
          return true;
      }
  
      @Override
      public boolean canSeekBackward() {
          return true;
      }
  
      @Override
      public boolean canSeekForward() {
          return true;
      }
  
      @Override
      public int getBufferPercentage() {
          return 0;
      }
  
      @Override
      public int getCurrentPosition() {
          return mMediaPlayer.getCurrentPosition();
      }
  
      @Override
      public int getDuration() {
          return mMediaPlayer.getDuration();
      }
  
      @Override
      public boolean isPlaying() {
          return mMediaPlayer.isPlaying();
      }
  
      @Override
      public void pause() {
          mMediaPlayer.pause();
      }
  
      @Override
      public void seekTo(int i) {
          mMediaPlayer.seekTo(i);
      }
  
      @Override
      public void start() {
          mMediaPlayer.start();
      }
  
      @Override
      public boolean isFullScreen() {
          return false;
      }
  
      @Override
      public void toggleFullScreen() {
  
      }
  
      @Override
      public void onBufferingUpdate(MediaPlayer mp, int percent) {
  
      }
  
      @Override
      public void onCompletion(MediaPlayer mp) {
  
      }
  
  
  
      @Override
      public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
  
      }
  
      @Override
      public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
          mSurface = new Surface(surface);
      }
  
      @Override
      public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
  
      }
  
      @Override
      public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
          return false;
      }
  
      @Override
      public void onSurfaceTextureUpdated(SurfaceTexture surface) {
  
      }
  
      public void changePlayState(){
          if(mMediaPlayer.isPlaying()){
              mMediaPlayer.pause();
          }else{
              mMediaPlayer.start();
          }
      }
  
      public void startVideo(String url){
          if(mMediaPlayer!=null){
              mMediaPlayer.reset();
              mMediaPlayer.release();
              mMediaPlayer = new MediaPlayer();
          }else{
              mMediaPlayer = new MediaPlayer();
          }
          if(!mMediaPlayer.isPlaying()){
              try {
                  mMediaPlayer.setSurface(mSurface);
                  mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                  mMediaPlayer.setDataSource(url);
                  mMediaPlayer.prepareAsync();
                  mMediaPlayer.setOnCompletionListener(this);
                  mMediaPlayer.setOnBufferingUpdateListener(this);
                  mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
                  mMediaPlayer.setOnPreparedListener(this);
  
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  
  
      @Override
      public void onPrepared(MediaPlayer mp) {
          Log.i(VersysVideoPlayer.class.getSimpleName(), "ON PREPARED CALLED");
          mControllerView.setMediaPlayer(this);
          mControllerView.setAnchorView(mView);
          mControllerView.show();
          mProgress.setVisibility(View.GONE);
          mMediaPlayer.start();
      }
  
      //Touch listener to display video controls
      class ControlTouchListener implements View.OnTouchListener{
  
          @Override
          public boolean onTouch(View v, MotionEvent event) {
              if(event.getAction() == MotionEvent.ACTION_DOWN){
                  mControllerView.show();
              }
              return false;
          }
      }
  }
  </code></pre>
  
  <p><strong>ACTIVITY/ADAPTER</strong></p>
  
  <pre><code>public class VideoViewListActivity extends AppCompatActivity   {
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_video_view_list);
  
          //Create instance of Recycler view
          final RecyclerView videoList = (RecyclerView) findViewById(R.id.feed_list);
          LinearLayoutManager llm = new LinearLayoutManager(this);
          videoList.setLayoutManager(llm);
          videoList.setHasFixedSize(true);
  
          final List&lt;String&gt; list = new ArrayList&lt;&gt;();
          list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
          list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
          list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
          list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
          list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
          list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
          final VideoAdapter adapter = new VideoAdapter(list, this);
          videoList.setAdapter(adapter);
  
  
          videoList.addOnScrollListener(new RecyclerView.OnScrollListener() {
              @Override
              public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                  super.onScrolled(recyclerView, dx, dy);
                  TextureView view = adapter.getVideoPlayer();
                  Log.i("PERCENTAGE VISIBLE: ", String.valueOf(getVisiblePercent(adapter.getVideoPlayer())));
                  if(getVisiblePercent(view)==100) {
                      return;
                  }
                }
              }
          });
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.menu_video_view_list, menu);
          return true;
      }
  
  
      public static int getVisiblePercent(View v) {
          if (v.isShown()) {
              Rect r = new Rect();
              v.getGlobalVisibleRect(r);
              double sVisible = r.width() * r.height();
              double sTotal = v.getWidth() * v.getHeight();
              return (int) (100 * sVisible / sTotal);
          } else {
              return -1;
          }
      }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          // Handle action bar item clicks here. The action bar will
          // automatically handle clicks on the Home/Up button, so long
          // as you specify a parent activity in AndroidManifest.xml.
          int id = item.getItemId();
  
          //noinspection SimplifiableIfStatement
          if (id == R.id.action_settings) {
              return true;
          }
  
          return super.onOptionsItemSelected(item);
      }
  
  
      /**
       * Recycler View Adapter
       */
      class VideoAdapter extends RecyclerView.Adapter&lt;VideoAdapter.VideoFeedHolder&gt; {
  
          public TextureView mPreview;
          private CardView mCardView;
          private List&lt;String&gt; mUrls;
          private Context mContext;
          private Surface mSurface;
          VideoControllerView controller;
          private View mAnchor;
          private ProgressBar mProgressDialog;
          private ImageView mHolder;
          private int mPosition;
          private VersysVideoPlayer mVideoPlayer;
          OnItemClickListener mItemClickListener;
  
          public VideoAdapter(List&lt;String&gt; url, Context ctx) {
              mUrls = url;
              mContext = ctx;
              controller = new VideoControllerView(ctx);
          }
  
          @Override
          public VideoAdapter.VideoFeedHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
              View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.video_item_feed, viewGroup, false);
              VideoFeedHolder holder = new VideoFeedHolder(v);
              return holder;
          }
  
          @Override
          public void onBindViewHolder(final VideoFeedHolder videoFeedHolder, final int i) {
  
              final VersysVideoPlayer videoPlayer = new VersysVideoPlayer(mContext, videoFeedHolder.mTexturePreview, mProgressDialog, videoFeedHolder.controlHolder);
              videoFeedHolder.placeholder.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      videoPlayer.startVideo(mUrls.get(i));
                      videoFeedHolder.placeholder.setVisibility(View.GONE);
                      videoFeedHolder.bar.setVisibility(View.VISIBLE);
                  }
              });
  
              mPosition = i;
          }
  
          @Override
          public void onAttachedToRecyclerView(RecyclerView recyclerView) {
              super.onAttachedToRecyclerView(recyclerView);
          }
  
  
          public String getUrl() {
              return mUrls.get(mPosition);
          }
  
  
          @Override
          public int getItemCount() {
  
              return mUrls.size();
          }
  
          public TextureView getVideoPlayer() {
              return mPreview;
          }
  
  
          public class VideoFeedHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
  
              TextureView mTexturePreview;
              ProgressBar bar;
              ImageView placeholder;
              FrameLayout controlHolder;
              RelativeLayout touchLayout;
              public VideoFeedHolder(View itemView) {
                  super(itemView);
  
                  mTexturePreview = (TextureView) itemView.findViewById(R.id.video_player);
                  mPreview = mTexturePreview;
                  mCardView = (CardView) itemView.findViewById(R.id.cv);
                  bar = (ProgressBar)itemView.findViewById(R.id.buffereing);
                  placeholder = (ImageView) itemView.findViewById(R.id.holder);
                  mProgressDialog = bar;
  
                  controlHolder = (FrameLayout) itemView.findViewById(R.id.media_controller_anchor);
  
              }
  
              @Override
              public void onClick(View v) {
                  if (mItemClickListener != null) {
                      mItemClickListener.onItemClick(v, getAdapterPosition());
                  }
              }
          }
  
       }
  }
  </code></pre>
  
  <p><strong>VIDEO FEED ITEM XML</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"&gt;
  
      &lt;android.support.v7.widget.CardView
          android:layout_margin="10dp"
          android:layout_width="match_parent"
          android:layout_height="400dp"
          android:id="@+id/cv"&gt;
          &lt;RelativeLayout
              android:id="@+id/anchor"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"&gt;
              &lt;RelativeLayout
                  android:id="@+id/detail_layout"
                  android:layout_marginTop="10dp"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"&gt;
                  &lt;ImageView
                      android:id="@+id/profile_pic"
                      android:background="@drawable/profiler"
                      android:layout_marginLeft="10dp"
                      android:layout_width="50dp"
                      android:layout_height="50dp" /&gt;
  
                  &lt;TextView
                      android:id="@+id/user_name"
                      android:layout_alignTop="@+id/profile_pic"
                      android:layout_toRightOf="@+id/profile_pic"
                      android:text="Joe Bloggs"
                      android:layout_marginLeft="10dp"
                      android:textColor="#000000"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content" /&gt;
  
                  &lt;TextView
                      android:id="@+id/date"
                      android:layout_below="@+id/user_name"
                      android:layout_toRightOf="@+id/profile_pic"
                      android:layout_marginLeft="10dp"
                      android:text="10 Aug 2015"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content" /&gt;
  
                  &lt;TextView
                      android:id="@+id/desc"
                      android:layout_below="@+id/profile_pic"
                      android:layout_marginLeft="10dp"
                      android:text="This a sample video of a bird getting hit on the head and a rabbit waking from a nap!!"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content" /&gt;
              &lt;/RelativeLayout&gt;
              &lt;RelativeLayout
                  android:layout_below="@+id/detail_layout"
                  android:layout_margin="10dp"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"&gt;
                      &lt;TextureView
                          android:id="@+id/video_player"
                          android:layout_width="match_parent"
                          android:layout_height="match_parent" /&gt;
                     &lt;FrameLayout
                         android:id="@+id/media_controller_anchor"
                         android:layout_alignParentBottom="true"
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"&gt;
                     &lt;/FrameLayout&gt;
  
                      &lt;ImageView
                          android:id="@+id/holder"
                          android:layout_centerInParent="true"
                          android:background="@drawable/default_video_poster"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content" /&gt;
  
                      &lt;ProgressBar
                          android:id="@+id/buffereing"
                          android:visibility="gone"
                          android:layout_centerInParent="true"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content" /&gt;
              &lt;/RelativeLayout&gt;
          &lt;/RelativeLayout&gt;
      &lt;/android.support.v7.widget.CardView&gt;
  &lt;/RelativeLayout&gt;
  </code></pre>