我正在尝试按照我上网的课程中的教程构建类似Slack的聊天应用程序。
在教程中,教师使用的是ListView和OnItemClickListener方法,但我正在尝试使用recycleler视图,并且我坚持使用适配器中的onClickListener。
我试图在其他问题中找到答案,但找不到解决我问题的答案。最接近的是this和this
我的两个问题是: 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
}
您可以为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
})
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()方法中设置侦听器,因为它将被调用超过您的项目计数。