OnClickListener在我的适配器类中不起作用



我查看了网上发布的许多解决方案,但它们无法解决我的问题。可能适配器位置正在返回-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>
ViewHolder的init块中的adapterPosition返回-1。因此,我们只需要在侦听器中调用adapterPosition,这将解决问题,因为它将在创建视图持有者并将其附加到recyclerview时检索位置。在init块中设置任何类型的侦听器都是一种很好的方法,因为onCreateViewHolder只调用一次来创建视图持有者,而onBindViewHolder对同一视图持有者调用了多次,因此在onBindViewHolder中设置侦听器是多余的。
init {
thumbsUp.setOnClickListener {
val tweetId=snapshots.getSnapshot(adapterPosition).get("tweetId")
clickInterface.clickLike(tweetId.toString())
}
}

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

重新考虑您的应用程序体系结构。作为在RecyclerView中向DAO请求数据。适配器是相当奇怪的方法

是的,我希望ViewHolder的init块中getSnapshot调用中的adapterPosition返回-1。据我所知,所有适配器位置获取器都返回最后一个请求项的位置以供显示。但是,当您第一次创建ViewHolder时,还没有任何东西绑定到适配器(它仍处于设置阶段(,所以它的默认position可能是-1

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

onCreateViewHolder是适配器用来创建这些容器对象的调用。这是你扩展布局的地方,通常对视图进行findViewById,这样你就有了对它们的引用,你只需要设置TextView的文本,而不必每次更新视图时都对其进行fnd。

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

基本上,您不应该在ViewHolderinit块中使用adapterPosition,因为它在构造对象时会被调用一次。在这一点上,你不仅没有一个有意义的职位,而且随着职位的变化,这不是你想经常更新的吗?这就是onBindViewHolder的作用!它已经传递了位置和一切。这是设置状态的方法

最新更新