最近,做一个项目,使用 Preference 非常频繁,之前就很想写一些关于 android 数据存储的文章,这次机会来了。

先从小出着手吧,CheckBoxPreference 小巧可爱,使用简单。但是使用的时候,还是需要注意一些问题。下面开始讨论吧,欢迎拍砖!

app 运行之后,效果(很单调):

项目结构图:

这里关键是在 res/ 目录下面新建 xml 文件夹,然后新建我们需要的 Preference 布局(demo.xml)。

demo.xml 文件:

<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="Demo for checkboxpreference" > <CheckBoxPreference android:key="key_cbp" android:title="checkbox" android:summary="this is a demo" android:summaryOn="open me" android:summaryOff="close me" android:persistent="false"/> </PreferenceScreen>
代码部分,是一个继承自 PreferenceActivity 的类: package mark.zhang; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.util.Log; public class DemoActivity extends PreferenceActivity implements OnPreferenceClickListener, OnPreferenceChangeListener { private static final String KEY = "key_cbp"; private CheckBoxPreference cbp = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.demo); cbp = (CheckBoxPreference) findPreference(KEY); cbp.setOnPreferenceClickListener(this); cbp.setOnPreferenceChangeListener(this); } @Override public boolean onPreferenceClick(Preference preference) { Log.d("mark", "onPreferenceClick is invoked !"); return false; } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { Log.d("mark", "onPreferenceChange is invoked !"); return false; } }
在这个类中,实现两个接口,接口方法会在点击该 CheckBoxPreference 时回调。

似乎,上面的内容没有什么很难的地方,的确!但是运行 App 之后,你会发现CheckBox 不可以选择?!

在 API 的文档关于 onPreferenceChange 方法中有这么一句:

True to update the state of the Preference with the new value.
可以看出,在这个方法的结尾返回 true 就可以了,呵呵!这点要注意,细节决定效率嘛!

ok,再看第二个问题,我们知道 Preference 可以自动保存状态值,保存是以 xml 文件形式保存的,保存路径在 /data/data/packageName/shared_prefs/×××.xml,但是你到这个路径去找找绝对找不到?!

原因在于我们所写的 demo.xml 文件,在这个文件中,有这么一句:

android:persistent="false"
这就表示不会保存 CheckBoxPreference 这个值(是一个 boolean 值,选择上就是 true,否则就是false)了。

如果,你设置这个属性为 true,android 就会为你自动保存,看下图:

但是为什么会自动保存?为什么文件名称就是 mark.zhang_preference 呢?当然是代码决定的,看源码,就会一目了然了!

当我们点击 CheckBoxPreference 的时候,会触发事件:

protected void onClick() { super.onClick(); boolean newValue = !isChecked(); // in onBindView() an AccessibilityEventViewClickedType is sent to announce the change // not sending mSendAccessibilityEventViewClickedType = true; if (!callChangeListener(newValue)) { return; } setChecked(newValue); }
那麽,

setChecked(newValue)

方法就可以调用,

persistBoolean(checked);
方法,该方法是 Preference 类的方法,然后调用 PreferenceManager 相关的方法获取 SharedPreference 来保存文件。

最后,看一个小问题,就是如何动态获取 CheckBoxPreerence 的值呢?很简单,实现OnSharedPreferenceChangeListener 接口,看代码:

package mark.zhang; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.util.Log; public class DemoActivity extends PreferenceActivity implements OnPreferenceClickListener, OnPreferenceChangeListener, OnSharedPreferenceChangeListener { private static final String KEY = "key_cbp"; private CheckBoxPreference cbp = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.demo); cbp = (CheckBoxPreference) findPreference(KEY); cbp.setOnPreferenceClickListener(this); // 注册OnPreferenceChangeListene // cbp.setOnPreferenceChangeListener(this); // 注册 SharedPreferenceChangeListener // 以便回调 onSharedPreferenceChangeListener getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); } @Override public boolean onPreferenceClick(Preference preference) { Log.d("mark", "onPreferenceClick is invoked !"); if (cbp.isChecked()) { // false Log.d("mark", "cbp.isChecked() = " + cbp.isChecked()); } // return true; return false; } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (preference.getKey().equals(KEY)) { Log.d("mark", "onPreferenceChange is invoked !" + newValue); // true } // 不可以选择CheckBox // return false; // 可以选择CheckBox return true; } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals(KEY)) { boolean value = sharedPreferences.getBoolean(key, false); Log.d("mark", "onSharedPreferenceChanged is invoked !" + " and the value = " + value); } } @Override protected void onDestroy() { // 注销 SharedPreferenceChangeListener getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener( this); super.onDestroy(); } }
运行之后,可以看到如下打印信息:

D/mark ( 8077): onSharedPreferenceChanged is invoked ! and the value = false D/mark ( 8077): onPreferenceClick is invoked ! D/mark ( 8077): onSharedPreferenceChanged is invoked ! and the value = true D/mark ( 8077): onPreferenceClick is invoked ! D/mark ( 8077): cbp.isChecked() = true
提醒一点,如果不注册onSharedPreferenceChangListener:

getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
是不会回调onSharedPreferenceChanged 方法的。

数据存储: CheckBoxPreference相关推荐

  1. 英特尔 QLC 3D NAND 数据存储

    英特尔 QLC 3D NAND 数据存储 NAND是什么 由于SSD固态硬盘的普及,NAND这个词逐渐进入用户们的视线.许多厂商都在产品宣传中提到3D NAND颗粒等词汇,对于普通用户来讲,完全不知道 ...

  2. Android的数据存储方式

    1.Shared Preferences 2.文件存储数据 3.数据库 4.Content Provider存储数据,是所有应用程序之间数据存储和检索的一个桥梁,它的作用就是使得各个应用程序之间实现数 ...

  3. mysql更改数据库数据存储目录_MySQL更改数据库数据存储目录

    MySQL数据库默认的数据库文件位于/var/lib/mysql下,有时候由于存储规划等原因,需要更改MySQL数据库的数据存储目录.下文总结整理了实践过程的操作步骤. 1:确认MySQL数据库存储目 ...

  4. AS3.0编程 So本地数据存储(“超级cookies”)--AS3:Local SharedObject

    Flash影片运行过程中,大多数的数据都存储于影片本身,一旦影片被关闭,这些数据也就从内存中被清除掉,下次运行时,数据将从头开始.若想存储数据或者让客户端的多个影片共享同一组数据,就要想办法把数据存储 ...

  5. Java中数据存储方式

    2019独角兽企业重金招聘Python工程师标准>>> 1. 寄存器(register).这是最快的存储区,因为它位于不同于其他存储区的地方--处理器内部.但是寄存器的数量极其有限, ...

  6. IOS数据存储之文件沙盒存储

    前言: 之前学习了数据存储的NSUserDefaults,归档和解档,对于项目开发中如果要存储一些文件,比如图片,音频,视频等文件的时候就需要用到文件存储了.文件沙盒存储主要存储非机密数据,大的数据. ...

  7. 华为云大数据存储的冗余方式是三副本_大数据入门:HDFS数据副本存放策略

    大数据处理当中,数据储存始终是一个重要的环节,从现阶段的市场现状来说,以Hadoop为首的大数据技术框架,仍然占据主流地位,而Hadoop的HDFS,在数据存储方面,仍然得到重用.今天的大数据入门分享 ...

  8. BigData NoSQL —— ApsaraDB HBase数据存储与分析平台概览

    一.引言 时间到了2019年,数据库也发展到了一个新的拐点,有三个明显的趋势: 越来越多的数据库会做云原生(CloudNative),会不断利用新的硬件及云本身的优势打造CloudNative数据库, ...

  9. Android数据存储(三)——SQLite

    如果需要一个更加健壮的数据存储机制,则需要使用一个关系型数据库,在Android上,则为SQLlite. SQLite的特点:轻量级.嵌入式的.关系型数据库.可移植性好,易使用,小,高效且可靠,与使用 ...

  10. 希捷发布CORTX对象存储软件与开源社区,普惠超大规模数据存储

    数据存储和管理解决方案提供商希捷科技今日(10月29日)举行了"Let's Rethink Data"希捷科技Datasphere线上峰会.在本次峰会,希捷科技携手行业专家与生态合 ...

最新文章

  1. 可怕!公司部署了一个东西,悄悄盯着你
  2. 隧道凿岩机器人传感器_【谷企动态】天创电子管廊综合监控平台及机器人系统在国家电网项目顺利交付应用...
  3. C语言位运算实现加法
  4. 网络游戏,原罪和救赎
  5. MOSS中对列表的一些操作(创建,查询等)
  6. GDCM:gdcm::Dumper的测试程序
  7. VTK:图片之ImageGradientMagnitude
  8. 并发容器——ConcurrentHashMap
  9. 美图秀秀美化图片之【增强】模块界面与功能设计
  10. GD32VF103开发环境简单介绍
  11. sim868 c++二次开发基本完成
  12. 图样图森破:认识WiFi以后
  13. T32用的一个python脚本-替换文件中的文件夹路径字符串
  14. java nc接口开发_OA和NC系统集成接口开发方案.doc
  15. Python中Selenium模块的使用
  16. 信奥学习规划 信息学竞赛之路(2022.07.31)
  17. Wish官方推荐收款渠道 哪家比较好?
  18. 烽火MobileArk产品——企业移动设备管理软件
  19. 基于3dmax及Unity的虚拟博物展览馆
  20. 将字符串中的字母全部替换成字母的下一个字母,要是最后一位是z或Z则替换为a或A

热门文章

  1. 2019工程伦理慕课答案(2019秋)习题及期末答案
  2. jszip压缩服务器文件,JSZip压缩与解压的基本使用
  3. 矢量图svg转png的简单方法
  4. 笔记本安装黑苹果MacOS BigSur记录
  5. ECharts学习笔记(1)——使用关系图展示关联分析结果
  6. 遥感原理与应用网络课程学习
  7. 斐波那契堆(Fibonacci Heap)
  8. 如何改变win10鼠标样式
  9. 用户体验衡量指标分析
  10. wordpress英文主题怎样汉化成中文网站模板