无法使用onClickeListener为RecyclerView为简单的Singleton分配新值

问题描述 投票:0回答:2

我正在尝试按照我上网的课程中的教程构建类似Slack的聊天应用程序。

在教程中,教师使用的是ListView和OnItemClickListener方法,但我正在尝试使用recycleler视图,并且我坚持使用适配器中的onClickListener。

我试图在其他问题中找到答案,但找不到解决我问题的答案。最接近的是thisthis

我的两个问题是: 1.应用程序的主要活动在屏幕顶部显示一个标题,说明当前活动的频道。我已经创建了一个包含“当前频道”的单例,并且正在从该单例中提取标题的文本。我很难在点击时更改该单身人士的价值。

  1. 主要活动还在抽屉的列表视图中包含所有通道。我试图在点击频道时关闭抽屉,但这也没有发生。

这是我目前的适配器:

class ChannelsAdapter(val context: Context, val channels: ArrayList<Channel>) :
    RecyclerView.Adapter<ChannelsAdapter.Holder>() {


    inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val singleChannel = itemView.findViewById<TextView>(R.id.single_channel)

        val mainLayout = LayoutInflater.from(context).inflate(R.layout.activity_main, null)

        fun bindText(textVar: String, context: Context) {
            singleChannel.text = textVar
        }
    }

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.bindText(channels[position].toString(), context)

        holder.itemView.setOnClickListener {

            ChannelName.activeChannel = channels[position]

            holder.mainLayout.drawer_layout.closeDrawer(GravityCompat.START)

        }

    }

    override fun getItemCount(): Int {
        return channels.count()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelsAdapter.Holder {

        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.channel_list_layout, parent, false)
        return Holder(view)

    }

}

这是单身人士

object ChannelName {

var activeChannel : Channel? = null

}
android kotlin android-recyclerview onclicklistener recycler-adapter
2个回答
1
投票

您可以为setter变量重写activeChanell并调用之前添加的侦听器来通知您的Activity

object ChannelName {
    private val listeners = ArrayList<(Channel?) -> Unit>()

    fun addChannelNameChangedListener(listener: (Channel?) -> Unit) {
        listeners.add(listener)
    }

    fun removeChannelNameChangedListener(listener: (Channel?) -> Unit) {
        listeners.remove(listener)
    }

    var activeChannel: Channel? = null
        set(value) {
            field = value
            listeners.forEach { it.invoke(value) }
        }
}

Activity里面添加一个这样的监听器:

ChannelName.addChannelNameChangedListener { 
    // Do your operation
}

另一种解决方案是使用像Observable这样的LiveData utils,所以你不应该再担心Android生命周期了:

object ChannelName {
    val activeChannel: MutableLiveData<ChannelName> = MutableLiveData()
}

要更改适配器内的值,只需调用:

ChannelName.activeChannel.value = channels[position]

在你的活动Observe里面调用变量:

ChannelName.activeChannel.observe(this, Observer { 
    // Do your operation
})

0
投票
class ChannelsAdapter(val context: Context, val channels: ArrayList<Channel>) :
        RecyclerView.Adapter<ChannelsAdapter.Holder>() {

    private var itemClickListener: OnItemClickListener? = null

    fun setItemClickListener(itemClickListener: OnItemClickListener) {
        this.itemClickListener = itemClickListener
    }

    interface OnItemClickListener {
        fun onItemClick(position: Int)
    }

    inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {

        val singleChannel = itemView.findViewById<TextView>(R.id.single_channel)

        val mainLayout = LayoutInflater.from(context).inflate(R.layout.activity_main, null)

        fun bindText(textVar: String, context: Context) {
            singleChannel.text = textVar
        }

        override fun onClick(v: View?) {
            val position = adapterPosition
            itemClickListener?.let {
                if (position != RecyclerView.NO_POSITION) {
                    it.onItemClick(position)
                }
            }
        }
    }

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.bindText(channels[position].toString(), context)
    }

    override fun getItemCount(): Int {
        return channels.count()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChannelsAdapter.Holder {
        val view = LayoutInflater.from(parent.context)
                .inflate(R.layout.channel_list_layout, parent, false)
        return Holder(view)
    }
}

这样,您可以将setItemClickListener设置为活动中的适配器,并从recyclerView获取回调。您不应该在onBind()方法中设置侦听器,因为它将被调用超过您的项目计数。

© www.soinside.com 2019 - 2024. All rights reserved.