1

I am trying to implement an Instagram like recycler view in a fragment which shows Images and Videos. The images work fine. The videoview too works fine for the first time. But when I scroll down and the video view is removed from the displayed elements and then scroll back up, the video does not play.

Pretty sure the videoview isn't being initialized the second time.

What can I do to make it work?

Also when exactly is the onBindViewHolder called?

   class PostListAdapter(var posts: ArrayList<Post>) :
    RecyclerView.Adapter<PostListAdapter.PostViewHolder>() {


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = PostViewHolder(


        LayoutInflater.from(parent.context).inflate(com.example.mehfil.R.layout.item_post_v2, parent, false)

    )

    override fun getItemCount() = posts.size

    override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
        holder.bind(posts[position])


    }

My bind method looks like this...

  fun bind(post: Post) {

        if(post.type!!equals("video")) {
            //trigger video
            imageView.visibility = View.GONE
            videoView.visibility = View.VISIBLE
            try {
                videoView.setSource("mp4 video link")
            } catch (E: Exception) {
                Log.d("Video Error", E.toString())
            }
        }
        else
        {
            videoView.visibility=View.GONE
            imageView.visibility=View.VISIBLE
            //trigger images
            if(post.media!= null)
        {
            if(post.media!!.indexOf("http:")!= -1)
                post.media=post.media!!.replace("http","https")
            imageView.loadImage(post.media , progressDrawable)
            Log.d("Media link ",post.media)
        }

                       }

1 Answer 1

2

Use exoplayer if you want to play videos in recyclerview , it automatically saves instance and play video when scrolled up or down

Add this in gradle

implementation 'com.google.android.exoplayer:exoplayer:2.10.8'

add exoplayer widget where you declared imageview in xml like this

<com.google.android.exoplayer2.ui.PlayerView
                    android:id="@+id/exoPlayer"
                    android:layout_width="match_parent"
                    android:layout_height="200dp"
                    android:visibility="gone" />

Now you method looks like this using exoplayer in it

fun bind(post: Post) {

        if(post.type!!equals("video")) {
            //trigger video
            imageView.visibility = View.GONE
            exoplayer.visibility = View.VISIBLE
            try {
              val uri = Uri.parse(
                    video_path
                )
             val player = ExoPlayerFactory.newSimpleInstance(context)
                exoPlayer.setPlayer(player)
 // Produces DataSource instances through which media data is loaded.
                val dataSourceFactory: DataSource.Factory =
                    DefaultDataSourceFactory(
                        context,
                        Util.getUserAgent(context, "Appname")
                    )

                val videoSource: MediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
                    .createMediaSource(uri)
// Prepare the player with the source.
                // Prepare the player with the source.
                player.prepare(videoSource)
            } catch (E: Exception) {
                Log.d("Video Error", E.toString())
            }
        }
        else
        {
            exoplayer.visibility=View.GONE
            imageView.visibility=View.VISIBLE
            //trigger images
            if(post.media!= null)
        {
            if(post.media!!.indexOf("http:")!= -1)
                post.media=post.media!!.replace("http","https")
            imageView.loadImage(post.media , progressDrawable)
            Log.d("Media link ",post.media)
        }

                       }
4
  • 1
    Hey! Thanks for the detailed reply.The code is almost working but sometimes I land into this error , com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.Exynos.avc.dec, Format(1, null, null, video/avc, null, -1, null, [1920, 1080, 29.969496], [-1, -1]) Commented May 10, 2020 at 14:54
  • which device and did you test this code in more than one device? Commented May 10, 2020 at 14:57
  • @GurkeeratSondhi have you got the solution for "sometimes I land into this error , com.google.android.exoplayer2.ExoPlaybackException:" Commented Jan 4, 2021 at 13:35
  • 1
    I was making a mistake wherein I was loading multiple video views one after the other. If in case of doing that, you only load the active video view that is in focus in the recycle view, the problem will be more or less solved. Commented Jan 5, 2021 at 6:53

Not the answer you're looking for? Browse other questions tagged or ask your own question.