我正在按照在线课程中的教程,尝试构建一个类似于Slack的聊天应用程序。
在本教程中,讲师使用的是ListView和OnItemClickListener方法,但是我尝试使用回收站视图进行操作,并且卡在适配器中的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
}
答案 0 :(得分: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
}
替代解决方案是使用LiveData
之类的Observable
实用程序,因此您不必再担心Android生命周期:
object ChannelName {
val activeChannel: MutableLiveData<ChannelName> = MutableLiveData()
}
要更改适配器内部的值,只需调用:
ChannelName.activeChannel.value = channels[position]
在您的活动Observe
中,通过调用:
ChannelName.activeChannel.observe(this, Observer {
// Do your operation
})
答案 1 :(得分: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)
}
}
这样,您可以将ItemSetClickListener设置为活动中的适配器,并从recyclerView获取回调。 您不应在onBind()方法中设置侦听器,因为它的调用次数将超过您的项目计数。