android 点击屏幕 回调,Android 点击回调传递

概述

在使用MultiTypeAdapter实现RecyclerView多类型显示的时候,会创建一个ViewHolder和ViewBinder,此时如果要在Activity或者Fragment相应点击事件的时候,需要在ViewHolder和ViewBinder之间做传递。如果一个ViewHolder下有RecyclerView,然后也使用了MultiTypeAdapter,那么这个点击事件的回调将会是一件相当头疼的事情。

启发

在使用LifeCycle时,发现他只需要当前类实现LifecycleObserver,然后通过调用addObserver方法即可实现事件传递。由此想到点击事件是否也可以使用此种形式来实现。

DEMO

效果图

b9295d364781

demo (1).gif

实现

在受到LifeCycle的启发下,模仿这写了几个类。

OnItemClick

abstract class OnItemClick {

abstract fun addObserver(onItemClickObserver: OnItemClickObserver)

abstract fun addObserver(list: List?)

abstract fun getObserver(): List?

abstract fun dispatchObserver(onItemClickObserver: OnItemClickObserver)

abstract fun dispatchObserver(list: List?)

abstract fun removeObserver(onItemClickObserver: OnItemClickObserver)

abstract fun removeAll()

}

定义一系列的操作方法,包括添加、移除、传递等。

OnItemClickOwner

interface OnItemClickOwner {

fun getOnItemClick(): OnItemClick

}

一个点击事件如果在某个类中如果需要做操作,那么需要实现该接口。

OnItemClickRegistry

class OnItemClickRegistry() : OnItemClick() {

// 省略具体代码

}

继承OnItemClick,并实现具体的方法。

OnItemClickObserver

interface OnItemClickObserver

基本点击事件Observer

ViewBinder/ViewHolder 改造

BaseViewHolder

abstract class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), OnItemClickOwner {

var mT: T? = null

var mContext: Context = itemView.context

abstract fun setData(t: T)

}

BaseViewHolderWrapper

open class BaseViewHolderWrapper(itemView: View) :

BaseViewHolder(itemView), View.OnClickListener {

private val onItemRegistry = OnItemClickRegistry(this)

override fun setData(@NonNull t: T) {

mT = t

itemView?.setOnClickListener(this)

}

override fun onClick(v: View) {

}

fun getObserver(clazz: Class): R? {

getOnItemClick().getObserver()?.forEach {

if (clazz.isInstance(it)) {

@Suppress("UNCHECKED_CAST")

return it as R

}

}

return null

}

override fun getOnItemClick(): OnItemClick {

return onItemRegistry

}

}

BaseViewBinder

abstract class BaseViewBinder> : ItemViewBinder(), OnItemClickOwner {

private val onItemRegistry = OnItemClickRegistry(this)

override fun getOnItemClick(): OnItemClick {

return onItemRegistry

}

@LayoutRes

private val layoutId: Int

@LayoutRes

abstract fun getLayoutId(): Int

init {

layoutId = this.getLayoutId()

}

fun getItemView(inflater: LayoutInflater, parent: ViewGroup): View {

if (layoutId == 0) {

throw IllegalArgumentException("You must return a layout id.")

}

return inflater.inflate(layoutId, parent, false)

}

override fun onBindViewHolder(holder: R, item: T) {

holder.getOnItemClick().dispatchObserver(getOnItemClick().getObserver())

holder.setData(item)

}

}

这一层,对事件在OnBindViewHolder中做了一次传递,通过dispatchObserver方法,将ViewBinder中的事件传递到了ViewHolder中。

使用

Observer

interface Observer1 : OnItemClickObserver {

fun onClick1()

}

interface Observer2 : OnItemClickObserver {

fun onClick2()

}

定义两个点击事件。

Bean

data class Bean1(var name: String)

class Bean2

创建实体类,和Binder相对应。

ViewHolder

ViewHolder1

class ViewHolder1(itemView: View) : BaseViewHolderWrapper(itemView) {

private val textView = itemView.findViewById(R.id.textView)

override fun setData(t: Bean1) {

super.setData(t)

textView.text = t.name

}

override fun onClick(v: View) {

getObserver(Observer1::class.java)?.onClick1()

}

}

在覆写setData方法的时候,一定要调用super。不然事件无法传递。

响应事件的回调,只需要调用getObserver方法,然后传入对应的Observer,如果有,就直接调用方法。

ViewHolder2

class ViewHolder2(itemView: View) : BaseViewHolderWrapper(itemView) {

var recyclerView: RecyclerView = itemView.findViewById(R.id.recyclerView2)

private val adapter = RecyclerViewAdapter2(mContext)

init {

recyclerView.layoutManager = LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false)

recyclerView.adapter = adapter

adapter.submitList(listOf(

Bean1("第二层"),

Bean1("第二层"),

Bean1("第二层")

))

}

override fun setData(t: Bean2) {

super.setData(t)

adapter.getOnItemClick().dispatchObserver(getOnItemClick().getObserver())

}

override fun onClick(v: View) {

getObserver(Observer2::class.java)?.onClick2()

}

}

adapter传递事件,也是通过dispatchObserver方法。

ViewBinder

ViewBinder其实就不需要做什么事情了,比较简单。

class Binder1 : BaseViewBinder() {

override fun getLayoutId(): Int {

return R.layout.item_1

}

override fun onCreateViewHolder(inflater: LayoutInflater, parent: ViewGroup): ViewHolder1 {

return ViewHolder1(getItemView(inflater, parent))

}

}

class Binder2 : BaseViewBinder() {

override fun getLayoutId(): Int {

return R.layout.item_2

}

override fun onCreateViewHolder(inflater: LayoutInflater, parent: ViewGroup): ViewHolder2 {

return ViewHolder2(getItemView(inflater, parent))

}

}

Activity

注册

val binder1 = Binder1()

val binder2 = Binder2()

multiTypeAdapter.register(Bean1::class.java, binder1)

multiTypeAdapter.register(Bean2::class.java, binder2)

添加点击事件

binder1.getOnItemClick().addObserver(object : Observer1 {

override fun onClick1() {

Toast.makeText(this@MainActivity, "binder1 onClick1", Toast.LENGTH_SHORT).show()

}

})

binder2.getOnItemClick().addObserver(object : Observer1 {

override fun onClick1() {

Toast.makeText(this@MainActivity, "binder2 onClick1", Toast.LENGTH_SHORT).show()

}

})

binder2.getOnItemClick().addObserver(object : Observer2 {

override fun onClick2() {

Toast.makeText(this@MainActivity, "binder2 onClick2", Toast.LENGTH_SHORT).show()

}

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值