4.0版本 MutiItemAdapter中添加Holder的方式是否可以更简练些,下面是我的一些尝试
其实在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
}
}
其实在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 } }
这样就能省略很多addItemType的重复代码,而用反射单单创建一个实例应该还是比较容易接受的,但目前我遇到一个问题,就是如果才能更优雅的获取到Holder的实例呢,然后在其他特殊场景下进行数据的传递,例如我在列表中有一个Holder的数据需要根据外部的条件随时更改,如何才能优雅且快速的找到目标Holder呢?
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个 BaseVH。
你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener可独立成一个class。
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener可独立成一个class。
明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
最新版本是否同时支持下拉刷新,上拉加载更多和DiffAdapter,这种使用场景较多,希望以后版本中能实现
最新版本是否同时支持下拉刷新,上拉加载更多和DiffAdapter,这种使用场景较多,希望以后版本中能实现
肯定支持啊
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
你打个比方呢?是哪里获取 holder ?
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
你打个比方呢?是哪里获取 holder ?
很抱歉,最近需求太多了,一直没顾的上回复大佬您,具体的场景大概可以理解为 在一个列表中,存在很多Type的item,其中有一项是视频、一项是轮播图,假设这两种都有很多个,这时,当切换页面和进入后台时,如果才能合理的找到对应的Holder,然后将其中的Holder关闭播放/轮播呢?
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
你打个比方呢?是哪里获取 holder ?
很抱歉,最近需求太多了,一直没顾的上回复大佬您,具体的场景大概可以理解为 在一个列表中,存在很多Type的item,其中有一项是视频、一项是轮播图,假设这两种都有很多个,这时,当切换页面和进入后台时,如果才能合理的找到对应的Holder,然后将其中的Holder关闭播放/轮播呢?
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
}
这个方法不能做到么?
看了你的代码,并没有本质变化。对于一个 三方库 来说,这种过渡的封装显得没有必要,反而会丢失更多的自由性,每个人可以安装不同的业务情况,自己去封装个
BaseVH。 你所说到的 冗余 问题,其实处理起来很简单,例如OnMultiItemAdapterListener可独立成一个class。明白了,感谢大佬指导,那咱们的库有没有更优雅的获取Holder实例的方法呢?
你打个比方呢?是哪里获取 holder ?
很抱歉,最近需求太多了,一直没顾的上回复大佬您,具体的场景大概可以理解为 在一个列表中,存在很多Type的item,其中有一项是视频、一项是轮播图,假设这两种都有很多个,这时,当切换页面和进入后台时,如果才能合理的找到对应的Holder,然后将其中的Holder关闭播放/轮播呢?
override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) { }这个方法不能做到么?
在Fragment场景下中,切换不同的Fragment时,这个方法是不会执行的,还有前后台切换也不会执行