Search code examples
androidkotlinandroid-recyclerviewfirebaseui

OnClickListener is not working inside my adapter class


I looked at many solutions posted online but they couldn't solve my problem. Probably the adapter position is returning -1 but why?

    java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
        at java.util.ArrayList.get(ArrayList.java:439)
        at 
    com.firebase.ui.common.BaseObservableSnapshotArray.getSnapshot(BaseObservableSnapshotArray.java:70)
        at com.example.twitterclone.adapters.MyAdapter$TweetViewHolder.<init>(MyAdapter.kt:36)
        at com.example.twitterclone.adapters.MyAdapter.onCreateViewHolder(MyAdapter.kt:50)
        at com.example.twitterclone.adapters.MyAdapter.onCreateViewHolder(MyAdapter.kt:21)
        at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7078)
        at 

RecyclerViewAdapterCode:

    class MyAdapter(
    options: FirestoreRecyclerOptions<Tweet>,
    private val clickInterface: ClickInterface
    ):FirestoreRecyclerAdapter<Tweet, MyAdapter.TweetViewHolder>(options) {

    inner class TweetViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val profile =
            view.findViewById<de.hdodenhof.circleimageview.CircleImageView>(R.id.userProfile)
        val tweet = view.findViewById<TextView>(R.id.tweet)
        val like = view.findViewById<TextView>(R.id.totalLikes)
        val thumbsUp = view.findViewById<ImageView>(R.id.thumbsUp)
        val name=view.findViewById<TextView>(R.id.tweetUserName)
        init {


                val tweetId=snapshots.getSnapshot(adapterPosition).get("tweetId")
                thumbsUp.setOnClickListener {
                    clickInterface.clickLike(tweetId.toString())
                }

        }


    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): TweetViewHolder {
        val viewHolder = TweetViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.post_tweets_item, parent, false)
        )



        return viewHolder
    }

    override fun onBindViewHolder(
        holder: TweetViewHolder,
        position: Int,
        model: Tweet
    ) {
        holder.tweet.text = model.content.toString()
        holder.like.text = model.likes.toString()
        UserDao().getUser(model.uid!!).get().addOnSuccessListener {
            holder.name.text = it.get("name").toString()
            Glide.with(holder.profile.context).load(it.get("profileUrl").toString())
                .into(holder.profile)
        }


    }
     }

LayoutCode

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_margin="10dp"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="2dp"
        app:cardCornerRadius="5dp"
        app:cardElevation="2dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <de.hdodenhof.circleimageview.CircleImageView
                    android:id="@+id/userProfile"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_marginTop="8dp"
                    android:layout_marginLeft="8dp" />

                <TextView
                    android:id="@+id/tweetUserName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:textColor="@android:color/black"
                    android:layout_marginTop="8dp" />
            </LinearLayout>

            <TextView
                android:id="@+id/tweet"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="13dp"
                android:textColor="@android:color/black" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="80dp"
                    android:orientation="vertical"
                    android:padding="8dp">

                    <ImageView
                        android:layout_width="30dp"
                        android:id="@+id/thumbsUp"
                        android:clickable="true"
                        android:layout_height="30dp"
                        android:src="@drawable/ic_baseline_thumb_up_24" />

                    <TextView
                        android:id="@+id/totalLikes"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center" />
                </LinearLayout>

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="80dp"
                    android:orientation="vertical"
                    android:padding="8dp">

                    <ImageView
                        android:clickable="true"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:id="@+id/comments"
                        android:src="@drawable/ic_baseline_comment_24" />

                    <TextView
                        android:id="@+id/totalComments"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center" />
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </androidx.cardview.widget.CardView>

</LinearLayout>

Solution

  • adapterPosition in the ViewHolder's init block is returning -1. So we just need to call adapterPosition in the listener which will solve the issue, since it would retrieve the position when the view holder is created and attached to the recyclerview. Setting any kind of listeners in the init block is a good approach since the onCreateViewHolder called only once to create a view holder but the onBindViewHolder called multiple times for the same view holder, so setting listeners in the onBindViewHolder would be redundant.

       init {
    
                thumbsUp.setOnClickListener {
                    val tweetId=snapshots.getSnapshot(adapterPosition).get("tweetId")
                    clickInterface.clickLike(tweetId.toString())
                }
    
       }