持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情
接下来会对
Preference Library
官方库进行一个系列讲解,本篇文章是Preference Library
系列的第十篇,主要是介绍Preference Library
的多布局设置项实现机制。
设置项多布局如何实现的呢?
这里再说一次,Preference Library
就是RecyclerView
适配器实现的多布局item,所以实现多布局的原理就藏在RecyclerView.Adapter
的方法getItemViewType()
,这个说法对不对呢?Preference Library
也是这样实现的吗?
我们先回顾下平常业务项目中实现一个简单多布局的思路:
-
在方法
getItemViewType(position)
中根据下标索引position
返回对应的item布局类型,比如我们上拉加载,界面底部增加一个正在加载中的布局,这个时候position
等于数据源size-1时返回一个新的布局类型标识,这里记为B类型; -
在方法
onCreateViewHolder()
中根据position调用方法getItemViewType()
获取布局类型标识,当其为B时,就创建一个加载中的View并绑定到ViewHolder
中; -
在方法
onBindViewHolder()
中根据position调用方法getItemViewType()
获取布局类型标识,当为B时,就刷新加载中的View布局对应内容;
而Preference Library
就不是这样实现的,我们可以检索下getItemViewType()
在适配器中的调用位置,发现onCreateViewHolder()
和onBindViewHolder()
中都没有调用这个方法,所以其多布局的显示方式就不是我们想象中的这种了。
那实现多布局的秘密藏在哪里呢,我们看下关键方法onCreateViewHolder()
:
public PreferenceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final PreferenceResourceDescriptor descriptor = mPreferenceResourceDescriptors.get(
viewType);
//...
final View view = inflater.inflate(descriptor.mLayoutResId, parent, false);
//...
return new PreferenceViewHolder(view);
}
可以看到这个创建的item布局是从PreferenceResourceDescriptor
获取的,可以简单理解为这个对象集合就是适配器的数据源,这个对象我们之前的文章有讲,其内部包装了Preference
。
所以最终创建这个item布局的是最终是通过Preference
拿到的布局资源id,随后进行inflate加载的,到了这里,相信你就会明白Preference Library
多布局的实现机制了:
通过数据源的每个对象持有这个对象需要创建的item布局资源id,然后在
onCreateViewHolder()
中根据下标最终拿到这个资源id进行创建布局,并绑定到ViewHolder中。
顺便说一下,这个实现多布局的方式,对于RecyclerView
的复用机制而言,不太友好。
这里以其最后一级缓存中的RecyclerViewPool
说明:
想要复用RecyclerViewPool
中的ViewHolder有一个条件就是对应的viewType
要相同,viewType
就是通过getItemViewType()
进行获取的,问题就在这个方法中:
public int getItemViewType(int position) {
final Preference preference = this.getItem(position);
PreferenceResourceDescriptor descriptor = new PreferenceResourceDescriptor(preference);
int viewType = mPreferenceResourceDescriptors.indexOf(descriptor);
if (viewType != -1) {
return viewType;
}
//...
}
可以看到,这里返回的ViewType
类型对应PreferenceResourceDescriptor
在集合mPreferenceResourceDescriptors
中的索引下标,这个也就导致了每个PreferenceResourceDescriptor
的viewType
都是不相同的,即使两个设置项Preference
比如都是EditTextPreference
的实例,下标不同viewtype也就不同,那自然也不会发生复用。
总结
本篇文章主要是讲解了Preference Library
实现多布局设置项的原理,希望能对你有所帮助。
参考文章
合体篇:设置界面的开发利器Preference Library,源码浅析一下