其实在MultiItemAdapter添加各种addItemType会导致代码冗余的很,适当的抽离和使用反射会使代码简介很多很多,比如我在项目中的尝试:
class DetailsAdapter : BaseMultiItemAdapter<Floors>() {
init {
// 根据type添加返回type 滑动时会根据对应额Position去创建对应的Holder
onItemViewType { position, list ->
list[position].itemType
}
addDetailsVH(T_BRAND_HEADER.hashCode(), GDBrandHeaderVH::class.java, R.layout.item_vh_details_brand_header)
addDetailsVH(T_TOP_BANNER.hashCode(), GDTopBannerVH::class.java, R.layout.item_vh_details_top_banner)
addDetailsVH(T_PRESALE_PRICE.hashCode(), GDPresalePricesVH::class.java,R.layout.item_vh_details_presale_prices)
addDetailsVH(T_ACTIVITY_PRICE.hashCode(), GDActivityPricesVH::class.java, R.layout.item_vh_activity_prices)
......
}
/**
* 通过传递的过来的Class类型,创建出对应的ViewHolder
*/
private fun <E : DetailsEntity, T : BaseGDVH<E>> addDetailsVH(
itemType: Int, // holder类型
vh: Class<T>, // holder类名
@LayoutRes layoutId: Int // holder布局
) {
addItemType(itemType, object : OnMultiItemAdapterListener<DetailsEntity?, T> {
override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): T {
// 获取到默认的构造方法
val constructors = vh.declaredConstructors[0]
// 获取到绑定的view
val view = LayoutInflater.from(context).inflate(layoutId, parent, false)
return constructors.newInstance(view) as T
}
override fun onBind(holder: T, position: Int, item: DetailsEntity?) {
if (item == null) {
holder.onHiddenVh()
return
}
holder.onBindData(item as E)
}
// 商详的holder都是跨满屏幕
override fun isFullSpanItem(itemType: Int): Boolean {
return true
}
})
}
}
/**
* 抽离出来的一个基类,限定绑定类型,方便以后扩展
*/
abstract class BaseGDVH<T : DetailsEntity>(view: View) : RecyclerView.ViewHolder(view) {
abstract fun onBindData(data: T)
// 当类型解析失败(不匹配),或者是数据为空时,需要将当前的Holder直接隐藏掉
fun onHiddenVh() {
itemView.layoutParams.apply {
width = 0
height = 0
}
itemView.visibility = View.GONE
}
}
9条答案
按热度按时间ctrmrzij1#
其实在MultiItemAdapter添加各种addItemType会导致代码冗余的很,适当的抽离和使用反射会使代码简介很多很多,比如我在项目中的尝试:
这样就能省略很多addItemType的重复代码,而用反射单单创建一个实例应该还是比较容易接受的,但目前我遇到一个问题,就是如果才能更优雅的获取到Holder的实例呢,然后在其他特殊场景下进行数据的传递,例如我在列表中有一个Holder的数据需要根据外部的条件随时更改,如何才能优雅且快速的找到目标Holder呢?
vtwuwzda2#
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH
。你所说到的 冗余 问题,其实处理起来很简单,例如
OnMultiItemAdapterListener
可独立成一个class。wyyhbhjk3#
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH
。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener
可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
a7qyws3x4#
最新版本是否同时支持下拉刷新,上拉加载更多和DiffAdapter,这种使用场景较多,希望以后版本中能实现
emeijp435#
最新版本是否同时支持下拉刷新,上拉加载更多和DiffAdapter,这种使用场景较多,希望以后版本中能实现
肯定支持啊
k4emjkb16#
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH
。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener
可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
你打个比方呢?是哪里获取 holder ?
2w3kk1z57#
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH
。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener
可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
你打个比方呢?是哪里获取 holder ?
很抱歉,最近需求太多了,一直没顾的上回复大佬您,具体的场景大概可以理解为 在一个列表中,存在很多Type的item,其中有一项是视频、一项是轮播图,假设这两种都有很多个,这时,当切换页面和进入后台时,如果才能合理的找到对应的Holder,然后将其中的Holder关闭播放/轮播呢?
rwqw0loc8#
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH
。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener
可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
你打个比方呢?是哪里获取 holder ?
很抱歉,最近需求太多了,一直没顾的上回复大佬您,具体的场景大概可以理解为 在一个列表中,存在很多Type的item,其中有一项是视频、一项是轮播图,假设这两种都有很多个,这时,当切换页面和进入后台时,如果才能合理的找到对应的Holder,然后将其中的Holder关闭播放/轮播呢?
这个方法不能做到么?
alen0pnh9#
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH
。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener
可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
你打个比方呢?是哪里获取 holder ?
很抱歉,最近需求太多了,一直没顾的上回复大佬您,具体的场景大概可以理解为 在一个列表中,存在很多Type的item,其中有一项是视频、一项是轮播图,假设这两种都有很多个,这时,当切换页面和进入后台时,如果才能合理的找到对应的Holder,然后将其中的Holder关闭播放/轮播呢?
这个方法不能做到么?
在Fragment场景下中,切换不同的Fragment时,这个方法是不会执行的,还有前后台切换也不会执行