OnClickListener 在我的适配器中不工作 class

OnClickListener is not working inside my adapter class

看了很多网上的解决方案,都不能解决我的问题。适配器位置可能返回 -1,但为什么呢?

    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)
        }


    }
     }

布局代码

    <?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>

在onBindViewHolder中附上你的onClickListener

override fun onBindViewHolder(
            holder: TweetViewHolder,
            position: Int,
            model: Tweet
        ) {
            //your code of attaching data to view
            holder.thumbsUp.setOnClickListener{
              clickInterface.clickLike(model.tweetId.toString())
           }
         }

重新考虑您的应用程序架构。因为向 DAO 询问 RecyclerView.Adapter 中的数据是一种很奇怪的方法

是的,我希望您在 ViewHolder 的初始化块中的 getSnapshot 调用中的 adapterPosition 返回 -1。据我所知,all the adapter position getters return the position of the last requested item for display. 但是当你第一次创建 ViewHolders 时,还没有任何东西绑定到适配器(它仍然处于设置阶段),所以它的默认值 position 大概是 -1.

基本上 RecyclerView 的工作方式是这样的 - 您定义这些 ViewHolder 对象,这些对象基本上是显示每个项目的数据的东西。适配器没有为列表中的每个项目创建一个,而是创建了一些(足以填充可见区域和两边的一对),然后 通过移动它们来回收 它们当他们不在视野中时,更新他们的内容以代表不同的项目。

onCreateViewHolder 是适配器调用以创建那些容器对象的内容。在这里你可以膨胀布局并且通常在视图上做 findViewById 所以你有一个对它们的引用,你可以只设置一个 TextView 的文本而不是每次你想要的时候都必须找到视图更新它。

onBindViewHolder 是当您需要用不同项目的信息更新 ViewHolder 时调用的内容。这是您实际进行所有数据设置、更改图像等的地方,必要时更新点击侦听器。

基本上您不应该在 ViewHolderinit 块中使用 adapterPosition,因为在构造对象时会调用一次。那时您不仅没有有意义的职位,而且随着职位的变化,您不希望经常更新吗?这就是 onBindViewHolder 的用途!它具有传入的位置和所有内容。那就是你设置 state

的方法
ViewHolder 的初始化块中的

adapterPosition 返回 -1。所以我们只需要在侦听器中调用 adapterPosition 即可解决问题,因为它会在创建视图持有者并将其附加到 recyclerview 时检索位置。在 init 块中设置任何类型的侦听器是一个很好的方法,因为 onCreateViewHolder 只调用一次来创建一个视图持有者,而 onBindViewHolder 为同一个视图持有者调用多次,所以在 onBindViewHolder 是多余的。

   init {

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

   }