持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情
接下来会对
Preference Library官方库进行一个系列讲解,本篇文章是Preference Library系列的第七篇,主要是介绍Preference Library的基本渲染原理,感兴趣的可以了解下。
历史文章
练气篇:设置界面的开发利器Preference Library,了解一下~
筑基篇:设置界面的开发利器Preference Library,了解一下~
金丹篇:设置界面的开发利器Preference Library,了解一下~
元婴篇:设置界面的开发利器Preference Library,了解一下~
化神篇:设置界面的开发利器Preference Library,了解一下~
炼虚篇:设置界面的开发利器Preference Library,了解一下~
Preference Library实质是个啥?
这里直接给一个整体的总结:
Preference Library就是一个基于RecyclerView实现的多布局框架,每一个Preference层次结构(设置项)都是RecyclerView的item,每一个不同的Preference层次结构都是一种类型的布局。
我们负责管理Preference的PreferenceGroupAdapter就继承了RecyclerView.Adapter:
再比如Preference是被PreferenceResourceDescriptor,而每个布局对应的PreferenceViewHolder中的itemView就是通过:PreferenceResourceDescriptor获取Preference持有的布局资源id即mLayoutResId属性进行inflate获取的,这一点我们可以看下熟悉onCreatViewHolder()方法:
接下来我们就从SwitchPreferenceCompat作为入口,观察其是如何经过一步步渲染到界面上的。
SwitchPreferenceCompat是如何渲染的?
switchPreferenceCompatStyle样式属性
这里从SwitchPreferenceCompat的构造方法说起:
关键就在于R.attr.switchPreferenceCompatStyle提供的style上面,我们走进入看看:
可以看到我们熟悉CheckBoxPreference、SeekBarPreference、SwitchPreferenceCompat等等都有对应的style在这里配置,也就是各个设置项渲染的原理入口就在这里,这里我们只是讲解SwitchPreferenceCompat这个设置项对应的style配置(对应上图第三个红框):
看到配置的android:layout属性了吧,这是一个关键,我们看下preference_material.xml布局:
<LinearLayout
android:gravity="center_vertical"
android:clipToPadding="false"
android:baselineAligned="false">
<include layout="@layout/image_frame"/>
<RelativeLayout
android:layout_weight="1">
<TextView
android:id="@android:id/title"/>
<TextView
android:id="@android:id/summary"/>
</RelativeLayout>
<LinearLayout
android:id="@android:id/widget_frame"/>
</LinearLayout>
其中这个就是SwitchPreferenceCompat最终渲染到界面上的根布局,比如左边image_frame是图标,中间上面是title,下面是summary,后面却不是我们想象的切换按钮,而是一个id为widget_frame的LinearLayout布局,这个后面会讲解。
除此之外,Preference.SwitchPreferenceCompat.Material会通过.的方式继承Preference.SwitchPreferenceCompat配置的style:
核心就在android:widgetLayout这个属性配置的布局资源了,我们看下preference_widget_switch_compat.xml:
记住这个属性android:widgetLayout,这就是最终SwitchPreferenceCompat渲染到上面android:layout对应根布局中对应的最右边的切换按钮布局。
至于这个布局组合过程是怎么实现的,我们就得看下代码了,关键类就是Preference和PreferenceGroupAdapter。
我们先看下Preference的构造方法。
Preference解析上面两个属性配置的布局资源
这个就是在Preference(SwitchPreferenceCompat父类)的构造方法里面:
通过TypedArrayUtils.getResourceId就拿到了对应上面android:layout和android:widgetLayout的资源引用,并分别保存到mLayoutResId和mWidgetLayoutResId属性中。
PreferenceGroupAdapter实现最终组合
这个最终是在onCreateViewHolder中处理的:
-
上面有讲过
PreferenceResourceDescriptor封装了Preference,也就是SwitchPreferenceCompat; -
调用其
mLayoutResId方法,其实就是间接拿到了SwitchPreferenceCompat父类的mLayoutResId(就是上面保存的SwitchPreferenceCompat最终渲染到界面上的根布局),并inflate生成View: -
拿到上面生成
View的widget_frameid对应组件,即Leanerlayout,最终将mWidgetLayoutResId(就是上面保存的SwitchPreferenceCompat父类引用的mWidgetLayoutResId对应的切换布局)添加到该Leanerlayout中,这就完成了最终的界面组合; -
然后将最终生成的View传到
PreferenceViewHolder中生成ViewHolder;
总结
本篇文章主要是以
SwitchPreferenceCompat作为入口,窥探了Preference Library的渲染机制,希望能对你有所帮助,可以点个赞支持下。