一,概要
Preference作为setting核心框架,笔者对此框架做一个简单的解析,androidx.preference本质是对设置领域提供了一层View封装,以android view本身的策略模式进行二次开发,将常用的一些设置样式封装到不同的Preference中,以达到快速开发设置相关功能。并且,此风格与原生setting保持了一致,给用户提供了一致性体验。
以下是该框架类图,
二,入门
1,创建一个空Activity,如下,
2,创建SettingFragment,继承PreferenceFragmentCompat
3,重写onCreatePreferences,方法,此方法在Fragment#onCreate回调,并且通过setPreferenceFromResource解析preference的xml资源。
4,创建prefer_setting.xml,如下,
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory app:title="DJI账户">
<Preference
app:key="login_dji_account"
app:summary="点击事件"
app:title="点我呀" />
<Preference
app:enabled="false"
app:key="logout_dji_account"
app:title="不可点击" />
</PreferenceCategory>
<PreferenceCategory
app:initialExpandedChildrenCount="0"
app:title="Dialog类型组件">
<EditTextPreference
app:enableCopying="true"
app:key="rtmp_url_pre"
app:summary="请设置"
app:title="直播推流地址"
app:useSimpleSummaryProvider="true" />
<ListPreference
app:enableCopying="true"
app:entries="@array/finishedAction"
app:entryValues="@array/finishedAction_values"
app:key="uav_finishedAction"
app:summary="返航"
app:title="任务结束动作"
app:useSimpleSummaryProvider="true" />
<MultiSelectListPreference
app:entries="@array/failSafe"
app:entryValues="@array/failSafe_values"
app:key="multi_select_list"
app:summary="悬停"
app:title="失控动作" />
</PreferenceCategory>
<PreferenceCategory app:title="其他的组件">
<Preference
app:summary="点击可以跳转到百度欸"
app:title="跳转Preference">
<intent
android:action="android.intent.action.VIEW"
android:data="http://www.baidu.com" />
</Preference>
<SwitchPreferenceCompat
app:key="uav_maxFlightRadiusEnabled"
app:selectable="true"
app:summary="设置无人机最大可飞行半径距离"
app:summaryOn="建议关闭此功能,否则将限制设备最大飞行距离"
app:title="限远开关" />
<EditTextPreference
app:dependency="uav_maxFlightRadiusEnabled"
app:key="uav_maxFlightRadius"
app:summary="2000"
app:title="限远(米)"
app:useSimpleSummaryProvider="true" />
<Preference
app:icon="@mipmap/ic_launcher"
app:key="icon"
app:summary="可以带Icon的Preference"
app:title="图标" />
<Preference
app:key="single_line_title"
app:singleLineTitle="true"
app:summary="但是下面的summary就不行了,它依然还是可以换行的,毕竟是注释信息嘛"
app:title="这个超级长,并且他不会换行,自带省略号的Preference" />
<DropDownPreference
app:entries="@array/finishedAction"
app:entryValues="@array/finishedAction_values"
app:key="dropdown"
app:title="点我!点我!点我!"
app:useSimpleSummaryProvider="true" />
<SeekBarPreference
app:defaultValue="20"
app:key="seekbar"
app:title="基本飞行速度(m/s)" />
</PreferenceCategory>
</androidx.preference.PreferenceScreen>
效果如下图,
三,深度解析
1,PreferenceFragmentCompat
笔者暂且从入口PreferenceFragmentCompat#onCreate讲起,如下
首先,创建一个PreferenceManager,关于此类作用见下文。随后,调用onCreatePreferences方法,这是一个abstract方法,子类必须实现,主要来加载xml文件,解析view-tree,笔者跟进。
跟进setPreferenceFomResource,
从xml文件中膨胀出PreferenceScreen,可知,PreferenceScre