合体篇:设置界面的开发利器Preference Library,源码浅析一下

1,286 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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层次结构都是一种类型的布局。

我们负责管理PreferencePreferenceGroupAdapter就继承了RecyclerView.Adapter

image.png

再比如Preference是被PreferenceResourceDescriptor,而每个布局对应的PreferenceViewHolder中的itemView就是通过:PreferenceResourceDescriptor获取Preference持有的布局资源id即mLayoutResId属性进行inflate获取的,这一点我们可以看下熟悉onCreatViewHolder()方法:

image.png

接下来我们就从SwitchPreferenceCompat作为入口,观察其是如何经过一步步渲染到界面上的。

SwitchPreferenceCompat是如何渲染的?

image.png

switchPreferenceCompatStyle样式属性

这里从SwitchPreferenceCompat的构造方法说起:

image.png

关键就在于R.attr.switchPreferenceCompatStyle提供的style上面,我们走进入看看:

image.png

可以看到我们熟悉CheckBoxPreferenceSeekBarPreferenceSwitchPreferenceCompat等等都有对应的style在这里配置,也就是各个设置项渲染的原理入口就在这里,这里我们只是讲解SwitchPreferenceCompat这个设置项对应的style配置(对应上图第三个红框):

image.png

看到配置的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_frameLinearLayout布局,这个后面会讲解。

除此之外,Preference.SwitchPreferenceCompat.Material会通过.的方式继承Preference.SwitchPreferenceCompat配置的style:

image.png

核心就在android:widgetLayout这个属性配置的布局资源了,我们看下preference_widget_switch_compat.xml

image.png

记住这个属性android:widgetLayout,这就是最终SwitchPreferenceCompat渲染到上面android:layout对应根布局中对应的最右边的切换按钮布局

至于这个布局组合过程是怎么实现的,我们就得看下代码了,关键类就是PreferencePreferenceGroupAdapter。 我们先看下Preference的构造方法。

Preference解析上面两个属性配置的布局资源

这个就是在Preference(SwitchPreferenceCompat父类)的构造方法里面:

image.png

通过TypedArrayUtils.getResourceId就拿到了对应上面android:layoutandroid:widgetLayout的资源引用,并分别保存到mLayoutResIdmWidgetLayoutResId属性中。

PreferenceGroupAdapter实现最终组合

这个最终是在onCreateViewHolder中处理的:

image.png
  1. 上面有讲过PreferenceResourceDescriptor封装了Preference,也就是SwitchPreferenceCompat

  2. 调用其mLayoutResId方法,其实就是间接拿到了SwitchPreferenceCompat父类的mLayoutResId(就是上面保存的SwitchPreferenceCompat最终渲染到界面上的根布局),并inflate生成View:

    image.png
  3. 拿到上面生成Viewwidget_frameid对应组件,即Leanerlayout,最终将mWidgetLayoutResId(就是上面保存的SwitchPreferenceCompat父类引用的mWidgetLayoutResId对应的切换布局)添加到该Leanerlayout中,这就完成了最终的界面组合;

  4. 然后将最终生成的View传到PreferenceViewHolder中生成ViewHolder;

总结

本篇文章主要是以SwitchPreferenceCompat作为入口,窥探了Preference Library的渲染机制,希望能对你有所帮助,可以点个赞支持下。