目录

1.从PreferenceScreen 中 删除某个Preference

2. Preference类图

3.  Activity&Fragment / Preference&Fragment 组合使用

4. Actionbar (标题: 显示与隐藏 )

4.1  AppCompatActivity  默认有标题

4.2 PreferenceActivity 默认没有标题

5. Preference 点击回调事件(OnPreferenceClickListener 、OnPreferenceChangeListener)

6. persistent  是否存储在内存中

7. SharedPreferences


1.从PreferenceScreen 中 删除某个Preference

(1) . 先获取PreferenceScreen

PreferenceScreen ps = getPreferenceScreen();

(2).  获取要删除的Preference

Preference pf = findPreference(pfKey); // pfKey 为String类型3. 删除
if (pf != null && ps != null) {ps.removePreference(pf);
}

其中removePreference 会返回 boolean 值, 删除成功true,  否正false

从 PreferenceCategory 中删除Preference 也是类似,先要获取PreferenceCategory

2. Preference类图

(1) PreferenceGroup 是Preference 的子类,也是一个抽象类,可以拥有一个或者多个Preference, 类似View 和ViewGroup.

(2) PreferenceScreen 和PreferenceCategory 是PreferenceGroup的子类,扩展少量方法

(3) PreferenceScreen 作为xml 布局文件根标签时,其设置的Titile 是不会显示的(需要设置主题支持Actionbar类型的,才会显示)

PreferenceScreen 内部再嵌套一个PreferenceScreen时(组合), 内部的PreferenceScreen会显示Titile(点跳转后!!!), 但是其内部的Preference需要点击后才会显示出来

如:

<PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android"<!--Title 不显示-->android:title="WiFi"android:key="first_preferencescreen"><CheckBoxPreferenceandroid:key="wifi enabled"android:title="WiFi" /><PreferenceScreenandroid:key="second_preferencescreen"<!--Title 显示-->android:title="WiFi settings"><!--内部Preference 不显示!!!! 需要点击进入后再显示Prefer wifi--><CheckBoxPreferenceandroid:key="prefer wifi"android:title="Prefer WiFi" /></PreferenceScreen>
</PreferenceScreen>

(4) 使用PreferenceCategory 可以显示标题, 并且Title这一行不能点击,因为PreferenceCategory内部覆写

public boolean isEnabled() {return false;
}

更多详细可以参考 https://blog.csdn.net/weixin_31767183/article/details/77748421

3.  Activity&Fragment / Preference&Fragment 组合使用

其中,PreferenceFragmentCompat 可以自定义定制化的风格,作为父类提供一个app或者一个系统使用,使得风格统一。

(通过依赖库的方式编译进去,一样可以是androidx.preference的包名)

4. Actionbar (标题: 显示与隐藏 )

标题是否显示 与 它的主题 (Theme有关)

4.1  AppCompatActivity  默认有标题

    /*** Support library version of {@link android.app.Activity#getActionBar}.** <p>Retrieve a reference to this activity's ActionBar.** @return The Activity's ActionBar, or null if it does not have one.*/@Nullablepublic ActionBar getSupportActionBar() {return getDelegate().getSupportActionBar();}

有两种方式隐藏标题

一种是在AndroidManifest 配置NoActionBar主题, 如 android:theme="@style/Theme.AppCompat.NoActionBar"

        <activityandroid:name=".XXXXActivity"android:theme="@style/Theme.AppCompat.NoActionBar"><intent-filter><action android:name="android.intent.action.MAIN" /></intent-filter></activity>

另一种是在代码里配置, 如

getSupportActionBar().hide()

4.2 PreferenceActivity 默认没有标题

如果要显示标题, 在代码里配置主题 (可以引用android 库里的主题)

    @Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {if(Build.VERSION.SDK_INT> Build.VERSION_CODES.HONEYCOMB_MR2){this.setTheme(android.R.style.Theme_DeviceDefault);}
}

5. Preference 点击回调事件(onClick /OnPreferenceClickListener 、OnPreferenceChangeListener)

在 onBindViewHolder 的时候,设置 onClickListener,  这个listener 其实就是实现 View 的OnClickListener,   Preference 内部交给performClick 处理。 详见后面

    private final View.OnClickListener mClickListener = new View.OnClickListener() {@Overridepublic void onClick(View v) {performClick(v);}};public void onBindViewHolder(PreferenceViewHolder holder) {View itemView = holder.itemView;Integer summaryTextColor = null;itemView.setOnClickListener(mClickListener);

提供点击监听的回调接口给客户端, 客户端可以决定是否响应事件 以及 在更新Preference 前进行设置操作(如设置Summary)

通过返回true 或者 false 告诉系统。 (例如 客户端在CheckBoxPreference中设置了监听, 实现了OnPreferenceChangeListener, 但是返回值为false, 则不会进行更新操作checked)

    /*** Interface definition for a callback to be invoked when a {@link Preference} is* clicked.** @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>*      <a href="{@docRoot}reference/androidx/preference/package-summary.html">*      Preference Library</a> for consistent behavior across all devices.*      For more information on using the AndroidX Preference Library see*      <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.*/@Deprecatedpublic interface OnPreferenceClickListener {/*** Called when a Preference has been clicked.** @param preference The Preference that was clicked.* @return True if the click was handled.*/boolean onPreferenceClick(Preference preference);}
    /*** Interface definition for a callback to be invoked when the value of this* {@link Preference} has been changed by the user and is* about to be set and/or persisted.  This gives the client a chance* to prevent setting and/or persisting the value.** @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>*      <a href="{@docRoot}reference/androidx/preference/package-summary.html">*      Preference Library</a> for consistent behavior across all devices.*      For more information on using the AndroidX Preference Library see*      <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.*/@Deprecatedpublic interface OnPreferenceChangeListener {/*** Called when a Preference has been changed by the user. This is* called before the state of the Preference is about to be updated and* before the state is persisted.** @param preference The changed Preference.* @param newValue The new value of the Preference.* @return True to update the state of the Preference with the new value.*/boolean onPreferenceChange(Preference preference, Object newValue);}

performClick 里的逻辑, 如果有为Preference 设置intent ,则会调用startActivity 跳转

    @RestrictTo(LIBRARY_GROUP_PREFIX)public void performClick() {if (!isEnabled() || !isSelectable()) {return;}onClick();if (mOnClickListener != null && mOnClickListener.onPreferenceClick(this)) {return;}PreferenceManager preferenceManager = getPreferenceManager();if (preferenceManager != null) {PreferenceManager.OnPreferenceTreeClickListener listener = preferenceManager.getOnPreferenceTreeClickListener();if (listener != null && listener.onPreferenceTreeClick(this)) {return;}}if (mIntent != null) {Context context = getContext();context.startActivity(mIntent);}}

6. persistent  是否存储在内存中(android:persistent="true")

        <!-- Whether the Preference stores its value to the storage. --><attr name="persistent" />
    <!-- Flag to control special persistent mode of an application.  This shouldnot normally be used by applications; it requires that the system keepyour application running at all times. --><attr name="persistent" format="boolean" />

如果是false, 则退出Preference 后,再进入, 值不会保存。

6.1  CheckBoxPreference(TwoStatePreference)

在响应onClick 的时候,会回调(如果有注册监听), 并在setChecked的时候,调用persistXXX(例如 persistBoolean) 进行存储。

因此使用Preference 后, 会对其xml 定义的key值进行存储, 不需要手动调用SharePreference.edit.putXXX(key, value).apply 进行存储。

默认值可以用 android.defaultValue 设置, 会存储到Preference 对应的SharePreference中

//TwoStatePreference.java@Overrideprotected void onClick() {super.onClick();final boolean newValue = !isChecked();if (callChangeListener(newValue)) {setChecked(newValue);}}/*** Sets the checked state and saves it to the {@link SharedPreferences}.** @param checked The checked state.*/public void setChecked(boolean checked) {// Always persist/notify the first time; don't assume the field's default of false.final boolean changed = mChecked != checked;if (changed || !mCheckedSet) {mChecked = checked;mCheckedSet = true;persistBoolean(checked);if (changed) {notifyDependencyChange(shouldDisableDependents());notifyChanged();}}}
//Preference.java/*** Attempts to persist a boolean if this Preference is persistent.** @param value The value to persist.* @return True if this Preference is persistent. (This is not whether the*         value was persisted, since we may not necessarily commit if there*         will be a batch commit later.)* @see #persistString(String)* @see #getPersistedBoolean(boolean)*/protected boolean persistBoolean(boolean value) {if (!shouldPersist()) {return false;}if (value == getPersistedBoolean(!value)) {// It's already there, so the same as persistingreturn true;}PreferenceDataStore dataStore = getPreferenceDataStore();if (dataStore != null) {dataStore.putBoolean(mKey, value);} else {SharedPreferences.Editor editor = mPreferenceManager.getEditor();editor.putBoolean(mKey, value);tryCommit(editor);}return true;}

6.2 普通Preference 存储字符串

/*** Attempts to persist a String if this Preference is persistent.** @param value The value to persist.* @return True if this Preference is persistent. (This is not whether the*         value was persisted, since we may not necessarily commit if there*         will be a batch commit later.)* @see #getPersistedString(String)*/protected boolean persistString(String value) {if (!shouldPersist()) {return false;}// Shouldn't store nullif (TextUtils.equals(value, getPersistedString(null))) {// It's already there, so the same as persistingreturn true;}PreferenceDataStore dataStore = getPreferenceDataStore();if (dataStore != null) {dataStore.putString(mKey, value);} else {SharedPreferences.Editor editor = mPreferenceManager.getEditor();editor.putString(mKey, value);tryCommit(editor);}return true;}

读取存储的字符串

    /*** Attempts to get a persisted String if this Preference is persistent.** @param defaultReturnValue The default value to return if either this*            Preference is not persistent or this Preference is not present.* @return The value from the data store or the default return*         value.* @see #persistString(String)*/protected String getPersistedString(String defaultReturnValue) {if (!shouldPersist()) {return defaultReturnValue;}PreferenceDataStore dataStore = getPreferenceDataStore();if (dataStore != null) {return dataStore.getString(mKey, defaultReturnValue);}return mPreferenceManager.getSharedPreferences().getString(mKey, defaultReturnValue);}

7. SharedPreferences

是一个接口???

根据同一个Context 获取到的SharePreference, 对命名相同key赋值或者读取时,实际是对同一个Key操作

public class ContextWrapper extends Context {@UnsupportedAppUsageContext mBase;//....@Overridepublic SharedPreferences getSharedPreferences(String name, int mode) {return mBase.getSharedPreferences(name, mode);}
}
 

8. 自定义Preference (如添加一个Preference 的属性值)

8.1 attrs.xml 添加自定义类型(declare-styleable)

其中,entryValue 为属性值,  groupKey 则可以拓展为当前Preference 属于哪一个Group 组

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="XXXPreference"><attr name="entryValue" format="string"></attr><attr name="groupKey" format="string"></attr></declare-styleable>
</resources>

8.2 获取自定义的属性值

通过TypedArray

    public XXXPreference(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.XXXPreference, 0, 0);String key = getKey();if (key != null) {mKey = key;}mGroupKey = a.getText(R.styleable.RadioPreference_groupKey).toString();mValue = a.getText(R.styleable.RadioPreference_entryValue).toString();a.recycle();}

注意:XML 定义的Preference 的默认构造函数是

    public XXXGroupPreference(Context context, AttributeSet attrs) {this(context, attrs, 0);setWidgetLayoutResource(R.layout.radiogroup);mContext = context;}

其中 radiogroup 为自定义的布局

8.3 XML 文件使用自定义Preference

其中app:entryValue 和  app:groupKey 即为自定义的属性  (xml文件的根标签 需要添加工具 xmlns:app="http://schemas.android.com/apk/res-auto")

                <com.example.Test.XXXPreferenceandroid:key="@string/pref_test"android:defaultValue="false"android:persistent="true"app:entryValue="@string/val_test_value"app:groupKey="@string/pref_test_group"android:title="@string/title_test" />

这样,可以为Preference 新增一个属性,并且可以在XML 使用时赋值, 简单明了。

(也可以在定义一个数组,在代码中为各个Preference的自定义属性赋值)

Android Preference 笔记相关推荐

  1. android preference 启动activity,Android PreferenceActivity 学习笔记

    在Ap中有时需要设置一些配置参数,这些参数通过配置文件保存. 为了设置这些参数,需要提供一个UI,针对这种需求,Android提供了preferenceActivity. PreferenceActi ...

  2. Android学习笔记之(一)开发环境搭建

    Android学习笔记之(一)开发环境搭建 zouxy09@qq.com http://blog.csdn.net/zouxy09 至于说Android是什么之类的俺就不啰嗦了,因为它离我们太近了.直 ...

  3. Android开发笔记(七十三)代码混淆与反破解

    代码混淆 ProGuard是ADT自带的apk混淆器,它的用途有: 1.压缩apk包的大小,能删除无用的代码,并简化部分类名和方法名. 2.加大破解源码的难度,因为部分类名和方法名被重命名,使得程序逻 ...

  4. Android学习笔记之AndroidManifest.xml文件解析(摘自皮狼的博客)

    Android学习笔记之AndroidManifest.xml文件解析 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它 ...

  5. Android开发笔记(一百零八)智能语音

    智能语音技术 如今越来越多的app用到了语音播报功能,例如地图导航.天气预报.文字阅读.口语训练等等.语音技术主要分两块,一块是语音转文字,即语音识别:另一块是文字转语音,即语音合成. 对中文来说,和 ...

  6. Android进阶笔记:Messenger源码详解

    Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...

  7. Android学习笔记21:ImageView获取网络图片

    Android平台有3种网络接口可以使用,它们分别是:java.net.*(标准java接口).org.apache(Apache接口)和android.net.*(Android网络接口).本文将使 ...

  8. Android进阶笔记:AIDL内部实现详解 (二)

    接着上一篇分析的aidl的流程解析.知道了aidl主要就是利用Ibinder来实现跨进程通信的.既然是通过对Binder各种方法的封装,那也可以不使用aidl自己通过Binder来实现跨进程通讯.那么 ...

  9. Android学习笔记(七):多个Activity和Intent

    根据www.mars-droid.com:Andriod开发视频教学,先跳过书本<Beginning Android 2>的几个章,我是这两个资源一起看,需要进行一下同步.先初步了解一下应 ...

最新文章

  1. 一份超详细的数据科学路线图!
  2. IOS代码实现常用控件UIButton、UISlider、UISwitch、UISegmentedControl
  3. sublime 2 中常用快捷键
  4. Coursera吴恩达《神经网络与深度学习》课程笔记(4)-- 浅层神经网络
  5. JAVA开发环境及其开发
  6. What is the difference between a domain and web hosting? (域名和虚拟主机)
  7. JS字符转为json对象
  8. Linux SHELL 学习随笔--for 循环
  9. SAP License:发票校验抬头税码选择清单
  10. android sqlite联合,在联合查询中,Android SQLiteorder by 计算列_sql_开发99编程知识库...
  11. VMware 安装windows XP SP3 镜像下载地址 回忆xp经典
  12. Deep Ordinal Regression Network for Monocular Depth Estimation
  13. 一个屌丝程序猿的人生(五十)
  14. Low-poly低面建模(低像素多边形)
  15. 微信单删和互删有什么区别?
  16. Vue项目启动时 卡在98% after emitting StylelintWebpackPlugin无法运行
  17. 「详解」imgaug 图像增强方法
  18. c语言设计二极管图形,二极管的电路符号及图片识别
  19. aix 安装oracle smit install_latest,Oracle 9i在AIX5L系统上的详细安装过程
  20. k8s部署-39-pod有哪几种部署方式呢?能不能回滚版本呢?带你了解。

热门文章

  1. JavaWeb1——互联网通信流程、共享资源文件、开发人员角色
  2. 无线网络速率协商过程
  3. 使用jxl导入excel文件 读取带有有效性的excel数据,遇到的问题
  4. unetbootin制作Linux启动U盘
  5. 文献 | AD影像学分类
  6. 如果反病毒软件不工作 有可能中了Rootkit Rootkit检测和清除还是有办法的
  7. 遇到女司机业余开滴滴,日入500!
  8. 暴雪首席任务设计师谈论任务设计
  9. 李白打酒:java实现
  10. 〖教程〗K8飞刀-网络安全CTF解题Web篇10例