Android 设置 Preference 随笔改造一

 原来一个应用中的设置是这样,如图,布局代码也就常规的那个样子, 里面的值也是用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 

第一次写 多多包涵,二 三, 和四,五 ,内容差不多,但最后没有去整理, 因为在真实改造时候确实是按照文章的先后顺序来的,当你的设置内容少,可能二,三就完了,  这也是改造中的一个过程,看肯定是不够的, 希望你也可以按照官方文档实际操作一番, 可能会发现对你更有用的介绍, 比如后面一些监听的设置. 如果你有关于文档任何地方更好的建议或写法 可以评论告诉我. 谢谢,

你可能感兴趣的:(Android 设置 Preference 随笔改造一)