问题描述
我在适配器中使用 getItemViewType()
来显示不同的视图
在我的聊天应用程序中。我面临的问题是当我必须在他们的消息旁边加载发送者和接收者的个人资料照片时。当我给 ImageView
一个不同的 ID 并按如下方式使用它们时,
override fun onBindViewHolder(holder: ViewHolder,position: Int) {
val chat:Chat = chat[position]
holder.showMessage.text = chat.message
Picasso.get().load(chat.userPic).into(holder.userPic)
Picasso.get().load(chat.recPic).into(holder.recPic)
}
class ViewHolder(v:View) : RecyclerView.ViewHolder(v){
val showMessage:TextView = v.findViewById(R.id.showMessage)
val userPic:CircleImageView = v.findViewById(R.id.userPic)
val recPic:CircleImageView = v.findViewById(R.id.recPic)
}
我收到一条错误消息,指出其中一个 ID 为空。当我给两个 ImageView
相同的 ID 并像下面一样使用它们时
override fun onBindViewHolder(holder: ViewHolder,position: Int) {
val chat:Chat = chat[position]
holder.showMessage.text = chat.message
Picasso.get().load(chat.userPic).into(holder.userPic)
Picasso.get().load(chat.recPic).into(holder.userPic)
}
class ViewHolder(v:View) : RecyclerView.ViewHolder(v){
val showMessage:TextView = v.findViewById(R.id.showMessage)
val userPic:CircleImageView = v.findViewById(R.id.userPic)
//val recPic:CircleImageView = v.findViewById(R.id.recPic)
}
它可以工作,但有时图像显示在错误的 ImageView
上,因为两个 ImageView
的 ID 相同。
我想到的一个解决方案是从数据库中检索当前登录用户(发件人)的照片 url,并将该值存储在适配器中的字符串中,如下所示,
val abc = Firebase.firestore
var userPic:String = ""
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ViewHolder {
return if(viewType == MSGTYPERIGHT){
val view1:View = LayoutInflater.from(parent.context).inflate(R.layout.chat_to_row,parent,false)
ViewHolder(view1)
}else{
val view2:View = LayoutInflater.from(parent.context).inflate(R.layout.chat_from_row,false)
ViewHolder(view2)
}
}
override fun getItemCount(): Int {
return chat.size
}
override fun onBindViewHolder(holder: ViewHolder,position: Int) {
val chat:Chat = chat[position]
abc.collection("users").document(Firebase.auth.uid!!).addSnapshotListener { value,_ ->
userPic = value?.get("profileUrl").toString()
}
holder.showMessage.text = chat.message
Picasso.get().load(userPic).into(holder.userPic)
Picasso.get().load(chat.recPic).into(holder.recPic)
}
class ViewHolder(v:View) : RecyclerView.ViewHolder(v){
val showMessage:TextView = v.findViewById(R.id.showMessage)
val userPic:CircleImageView = v.findViewById(R.id.userPic)
val recPic:CircleImageView = v.findViewById(R.id.recPic)
}
但是我从毕加索那里收到一条错误消息,说路径是空的,这意味着变量 userPic 包含我用它初始化的空字符串。
MessageAdapter.kt
class MessageAdapter(private val chat: ArrayList<Chat>):RecyclerView.Adapter<MessageAdapter.ViewHolder>() {
private val MSGTYPELEFT = 0
private val MSGTYPERIGHT = 1
override fun onCreateViewHolder(parent: ViewGroup,false)
ViewHolder(view2)
}
}
override fun getItemCount(): Int {
return chat.size
}
override fun onBindViewHolder(holder: ViewHolder,position: Int) {
}
class ViewHolder(v:View) : RecyclerView.ViewHolder(v){
val showMessage:TextView = v.findViewById(R.id.showMessage)
val userPic:CircleImageView = v.findViewById(R.id.userPic)
val recPic:CircleImageView = v.findViewById(R.id.recPic)
}
override fun getItemViewType(position: Int): Int {
val fuser = Firebase.auth
return if (chat[position].userId == fuser.uid) {
MSGTYPERIGHT
} else {
MSGTYPELEFT
}
}
}
我做错了什么,或者你们知道如何解决这个问题吗?
解决方法
您正在使用 getItemViewType()
,但在访问小部件时没有区分布局,这就是您遇到问题的原因。
将您的 onBindViewHolder()
更改为:
when(holder) {
is MSGTYPERIGHT -> {
//Put your code related to this ItemViewType's layout here
}
else {
//Put your other layout's code here
//You can use one condition like above for left as well,though.
}
}
当您使用 when
或 if else 检查持有者的类型时,在该范围内,IDE 会自动将您的持有者强制转换为该类型,因此,在第一种情况下,它将被强制转换为MSGTYPERIGHT
,然后,您将能够访问持有者特定的功能,IDE 将突出显示该范围内的 holder
变量。例如,如下图: