原来一个应用中的设置是这样,如图,布局代码也就常规的那个样子, 里面的值也是用SharedPreferences 自己去管理存储和获取,现在想用Preference 改造下, 看看哪种代码少,便于维护,
放一些连接, 主要根据这里面的教程去实现,中间有问题再去看别人写的博客和总结
https://developer.android.google.cn/guide/topics/ui/settings
https://developer.android.google.cn/jetpack/androidx/releases/preference?hl=zh_cn
项目gradle中添加
def preference_version = "1.1.1"
// Java language implementation
implementation
"androidx.preference:preference:$preference_version"// Kotlin
implementation
"androidx.preference:preference-ktx:$preference_version"
使用了androidx 的包项目需要支持androidx
一 概述
根据概述 在res/xml 下添加特殊的布局文件 和 fragment 和承载fragment 的 Activity
二 管理您的设置中
如果设置不多 可以不管 ,案例暂时用PreferenceCategory 把三个ip设置归为一栏
android:defaultValue="172.20.20.48:8080"
android:key="preference_printserver_ip"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/setting_inputipport" />
android:defaultValue="192.168.1.111"
android:key="preference_print_ip"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/setting_printip" />
android:defaultValue="172.20.20.48:8081"
android:key="preference_faceserver_ip"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/setting_faceipport" />
三 自定义您的设置
介绍了使用 findPreference 获取到每一个设置,和findById 功能类似
可用 isVisible 来设置空间的显示和隐藏
这里使用了动态更新摘要 还是比较有用 可以显示设置了的值,
然后是自定义对话框 这里只允许输入数字和符号 InputType.TYPE_NUMBER_FLAG_SIGNED
后面的设置添加intent 和点击监听暂时用不到,
private fun initEditText(editText:EditTextPreference?){
editText?.summaryProvider =
Preference.SummaryProvider
{ preference-> val text = preference.text
if (TextUtils.isEmpty(text)) {
"Not Set"
} else {
text
}
}
editText?.setOnBindEditTextListener{ editTextTemp->
editTextTemp.inputType = InputType.TYPE_NUMBER_FLAG_SIGNED
}
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.setting, rootKey)
val printserverip = findPreference
("preference_printserver_ip") val printip = findPreference
("preference_print_ip") val faceserverip = findPreference
("preference_faceserver_ip") initEditText(printserverip)
initEditText(printip)
initEditText(faceserverip)
}
四 管理您的设置
上面第二点不适用, 设置有点长,如果全部写一个页面里, 需要滑动,页面底部的设置滑动上不方便,所以还是根据官网中把每个拆开放单独的页面里.
android:fragment="com.insolu.insoledemo.fragment.MySetting_IP"
android:title="@string/setting_ipset">
把所有设置拆 成四个 点击后再进入具体的设置页面
主要是 android:fragment="com.insolu.insoledemo.fragment.MySetting_IP" 指定设置页面,具体跳转内部会自己管理
五 自定义您的设置
上面第三点已经描述了写法和作用 这里叙述下遇到的几个问题 EditTextPreference 和 layout 中使用EditText 有些设置不一样.比如ip 只需要数字,点 和:冒号 layout 使用 android:digits="1234567890.:" 设置就可以, 在EditTextPreference 中没有这个设置,文档中让使用inputType 但也没有数字加符号的设置,最后是设置的 filters ,创建一个IpFilter类实现 InputFilter 接口,创建 一个内部类IpFilterTemp 再继承IpFilter 重写 isAllowed 方法 .写法是参照android.text.LoginFilter 里面的UsernameFilterGMail 去编写的:
@Override
public boolean isAllowed(char c) {
// Allow [a-zA-Z0-9@.]
if ('0' <= c && c <='9')
return true;
if ('.' == c)
return true;
if (':' == c)
return true;
return false;
}
达到设置的目的. 网上搜到过类似做法.
2. 然后就是密码 的设置 使用 edit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD .
3. 定时重启有个时间的设置 格式要是 03:33 这种 ,做的比较暴力 直接在值修改的监听上,判断新的值是否满足 正则表达式
// 设置监听
rebootTime?.setOnPreferenceChangeListener{ preference, newValue->
val daytime: String = newValue as String
val temp = checkDayTime(daytime)
temp
}
// 返回是否满足正则表达是
fun checkDayTime(daytime: String): Boolean{
val regex2 ="^(((0|1)[0-9])|(2[0-3])):[0-5][0-9]"
return Pattern.matches(regex2, daytime)
}
六 使用
使用就很简单了 ,官网中的代码.
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)val name = sharedPreferences.getString("signature", "")
七 总结
整体修改 肯定是 Preference 代码更少, 以后维护也更方便, 最开始那种写法 在退出设置页面 还需要监听返回按键 退出还要把修改的项自己保存进 SharedPreferences , 而且所有的内容都在一个页面,整个文件代码也比较多, 以前的设置页面代码行数大约 720 现在大约 348 .布局代码 以前400 现在161 .少了很多,.
最后. Preference 现在默认使用的还是 SharedPreferences 存储数据 ,可以改为 datastore 存储数据.数据获取变成Flow 的方式.之后整改的时候再记录了.
datastore 的官方链接 : https://developer.android.google.cn/topic/libraries/architecture/datastore
第一次写 多多包涵,二 三, 和四,五 ,内容差不多,但最后没有去整理, 因为在真实改造时候确实是按照文章的先后顺序来的,当你的设置内容少,可能二,三就完了, 这也是改造中的一个过程,看肯定是不够的, 希望你也可以按照官方文档实际操作一番, 可能会发现对你更有用的介绍, 比如后面一些监听的设置. 如果你有关于文档任何地方更好的建议或写法 可以评论告诉我. 谢谢,