首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin Recycleview,如何为视图制作onItemClick

Kotlin Recycleview,如何为视图制作onItemClick
EN

Stack Overflow用户
提问于 2021-08-04 10:07:56
回答 2查看 47关注 0票数 0

我正在尝试实现一个功能:在recyclerView中,当您单击用户图像时,导航到userActivity,当您单击"gift“图标时,导航到otherActivity。

下面是我的Adapter.kt:

代码语言:javascript
复制
package Users.UserReceiveGiftItem

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gearsrun.www.R
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.user_receive_gift_item.view.*

class UserReceiveGiftAdapter(val userList : List<UserReceiveGiftItem>) : RecyclerView.Adapter<UserReceiveGiftAdapter.UserHolder>(){
    private lateinit var mListener :onItemClickListener
   interface onItemClickListener{
       fun onItemClick(view:View,position: Int)
   }

    fun setOnItemClickListener(listener: onItemClickListener){
        mListener = listener
    }


    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): UserHolder {
       val layoutInflater = LayoutInflater.from(parent.context)
        return UserHolder(layoutInflater.inflate(R.layout.user_receive_gift_item,parent,false),mListener)
    }

    override fun onBindViewHolder(holder: UserReceiveGiftAdapter.UserHolder, position: Int) {
         holder.render(userList[position])
    }


    override fun getItemCount(): Int = userList.size


    class UserHolder(val view : View,listener:onItemClickListener) : RecyclerView.ViewHolder(view){
       fun render(userList: UserReceiveGiftItem){
           Picasso.get().load(userList.user_img).into(view.user_img)
           view.user_name.text = userList.user_name
           view.time.text = userList.time
           view.userId.text = userList.userId
           view.giftImg.setImageResource(userList.giftImg)


       }
        init {
            view.setOnClickListener {
                listener.onItemClick(it,absoluteAdapterPosition)
            }

        }
    }
}

我在活动中使用:

代码语言:javascript
复制
package com.gearsrun.www.UI.Receive

import Users.UserReceiveGiftItem.UserReceiveGiftAdapter
import Users.UserReceiveGiftItem.UserReceiveGiftItem
import android.content.Intent
import android.graphics.drawable.ColorDrawable
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.ActionBar
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.gearsrun.www.R
import com.gearsrun.www.UI.Gift.AwaitingToUnwrapActivity
import com.gearsrun.www.UI.Sunflower.SunflowerAvailableActivity
import com.gearsrun.www.UI.User.UserDetailActivity
import kotlinx.android.synthetic.main.activity_who_receive_gift.*
import kotlinx.android.synthetic.main.user_receive_gift_item.view.*

class ReceiveActivity : AppCompatActivity() {
    val userList : List<UserReceiveGiftItem> = listOf(
        UserReceiveGiftItem(
            "https://i.pinimg.com/564x/63/85/68/63856877880614e0dab080071513156f.jpg",
            "Sharry",
            "10 mins ago",
            "517ddY",
            R.drawable.donut
        ),
     
    )
    lateinit var gift_unwrap : ImageView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_receive)
        changeColor(R.color.font_green)
        initRecycler()
        gift_unwrap = findViewById(R.id.gift_unwrap)
        gift_unwrap.setOnClickListener {


        }
    }
    private fun changeColor(resourseColor: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.statusBarColor = ContextCompat.getColor(applicationContext, resourseColor)
        }

        val bar: ActionBar? = supportActionBar
        if (bar != null) {
            bar.setBackgroundDrawable(ColorDrawable(resources.getColor(resourseColor)))
        }

    }

    fun initRecycler(){
        rvUser.layoutManager = LinearLayoutManager(this)
        val adapter = UserReceiveGiftAdapter(userList)
        rvUser.adapter = adapter
        adapter.setOnItemClickListener(object:UserReceiveGiftAdapter.onItemClickListener{
            override fun onItemClick(view: View, position: Int) {
               view.user_img.setOnClickListener {
                   val intent = Intent(this@ReceiveActivity,UserDetailActivity::class.java)
                   startActivity(intent)
               }
                view.giftImg.setOnClickListener {
                    val intent =Intent(this@ReceiveActivity,SunflowerAvailableActivity::class.java)
                    startActivity(intent)
                }
            }


        })

    }
}

它能够成功导航是有点罕见的,但是,它对第一次点击..Could没有反应,请看一下我的代码?提前谢谢你们!!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-04 13:20:09

您正在使用列表项的单击侦听器向其子项添加更多单击侦听器。因此,当您第一次单击它时,孩子们还没有侦听器,也不会做任何事情。父级和子级都有单击侦听器也很容易出错,因为如果您在单击时更改单击侦听器,将会发生什么情况是未知的。

相反,您应该在适配器中定义接口来处理这两种类型的单击。在ViewHolder中,仅在要单击的相关子对象上设置单击侦听器。

另外,我认为你滥用了lateinit。我会将该属性设置为可空。而且拥有一个属性值的setter函数是多余的。

如果将适配器类设为inner,那么就不必将侦听器的实例传递给视图持有者实例,如果更改适配器的侦听器,就会出现问题。

最后,我个人认为监听器应该返回列表项,而不是列表中的特定视图和位置。这些是外部类不需要知道的实现细节。

代码语言:javascript
复制
class UserReceiveGiftAdapter(val userList : List<UserReceiveGiftItem>) : RecyclerView.Adapter<UserReceiveGiftAdapter.UserHolder>(){
    var onItemClickListener: OnItemClickListener? = null

    interface OnItemClickListener{
        fun onUserClick(item: UserReceiveGiftItem)
        fun onGiftClick(item: UserReceiveGiftItem)
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): UserHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        return UserHolder(layoutInflater.inflate(R.layout.user_receive_gift_item,parent,false))
    }

    override fun onBindViewHolder(holder: UserReceiveGiftAdapter.UserHolder, position: Int) {
         holder.render(userList[position])
    }

    override fun getItemCount(): Int = userList.size

    inner class UserHolder(val view : View) : RecyclerView.ViewHolder(view){
        fun render(userList: UserReceiveGiftItem){
            Picasso.get().load(userList.user_img).into(view.user_img)
            view.user_name.text = userList.user_name
            view.time.text = userList.time
            view.userId.text = userList.userId
            view.giftImg.setImageResource(userList.giftImg)
        }

        init {
            view.user_img.setOnClickListener {
                onItemClickListener?.onUserClick(userList[absoluteAdapterPosition])
            }
            view.giftImg.setOnClickListener {
                onItemClickListener?.onGiftClick(userList[absoluteAdapterPosition])
            }
        }
    }
}

在活动或片段中:

代码语言:javascript
复制
adapter.onItemClickListener = object: UserReceiveGiftAdapter.OnItemClickListener {
    override fun onUserClick(item: UserReceiveGiftItem) {
        val intent = Intent(this@ReceiveActivity, UserDetailActivity::class.java)
        startActivity(intent)
    }

    override fun onGiftClick(item: UserReceiveGiftItem) {
        val intent = Intent(this@ReceiveActivity, SunflowerAvailableActivity::class.java)
        startActivity(intent)
    }
}
票数 1
EN

Stack Overflow用户

发布于 2021-08-04 13:34:07

看过你的代码后,我认为你是先将适配器设置到回收器视图,然后再将单击侦听器注入到适配器中。

这里发生的情况是,回收器视图中的一些项目已加载,此时它们不会有单击侦听器,

例如,如果你向下滚动,屏幕上新出现的项目将有适当的点击监听器,现在如果你向上滚动,前一个项目也会附加有监听器。

如何解决这个问题:

更改initRecycler()方法,如下所示:

代码语言:javascript
复制
fun initRecycler(){
        rvUser.layoutManager = LinearLayoutManager(this)
        val adapter = UserReceiveGiftAdapter(userList)
        adapter.setOnItemClickListener(object:UserReceiveGiftAdapter.onItemClickListener{
            override fun onItemClick(view: View, position: Int) {
               view.user_img.setOnClickListener {
                   val intent = Intent(this@ReceiveActivity,UserDetailActivity::class.java)
                   startActivity(intent)
               }
                view.giftImg.setOnClickListener {
                    val intent =Intent(this@ReceiveActivity,SunflowerAvailableActivity::class.java)
                    startActivity(intent)
                }
            }


        })

        //set adapter after setting click listener to your adapter.
        rvUser.adapter = adapter

    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68649337

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档