Android 設置 Preference 隨筆改造一

?原來一個應用中的設置是這樣,如圖,布局代碼也就常規(guī)的那個樣子, 里面的值也是用SharedPreferences 自己去管理存儲和獲取,現(xiàn)在想用Preference 改造下, 看看哪種代碼少,便于維護,


放一些連接, 主要根據(jù)這里面的教程去實現(xiàn),中間有問題再去看別人寫的博客和總結?

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"http:// Kotlin

implementation

"androidx.preference:preference-ktx:$preference_version"

使用了androidx 的包項目需要支持androidx

一 概述

根據(jù)概述 在res/xml 下添加特殊的布局文件 和 fragment? 和承載fragment 的 Activity

二 管理您的設置中

如果設置不多 可以不管 ,案例暫時用PreferenceCategory 把三個ip設置歸為一欄??

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

? ? <PreferenceCategory android:title="@string/setting_ipset">

? ? ? ? <EditTextPreference

? ? ? ? ? ? ? ? android:defaultValue="172.20.20.48:8080"

? ? ? ? ? ? ? ? android:key="preference_printserver_ip"

? ? ? ? ? ? ? ? android:selectAllOnFocus="true"

? ? ? ? ? ? ? ? android:singleLine="true"

? ? ? ? ? ? ? ? android:title="@string/setting_inputipport" />

? ? ? ? <EditTextPreference

? ? ? ? ? ? ? ? android:defaultValue="192.168.1.111"

? ? ? ? ? ? ? ? android:key="preference_print_ip"

? ? ? ? ? ? ? ? android:selectAllOnFocus="true"

? ? ? ? ? ? ? ? android:singleLine="true"

? ? ? ? ? ? ? ? android:title="@string/setting_printip" />

? ? ? ? <EditTextPreference

? ? ? ? ? ? ? ? android:defaultValue="172.20.20.48:8081"

? ? ? ? ? ? ? ? android:key="preference_faceserver_ip"

? ? ? ? ? ? ? ? android:selectAllOnFocus="true"

? ? ? ? ? ? ? ? android:singleLine="true"

? ? ? ? ? ? ? ? android:title="@string/setting_faceipport" />

? ? </PreferenceCategory>

</PreferenceScreen>

三 自定義您的設置

介紹了使用?findPreference 獲取到每一個設置,和findById 功能類似?

可用?isVisible 來設置空間的顯示和隱藏?

這里使用了動態(tài)更新摘要 還是比較有用 可以顯示設置了的值,

然后是自定義對話框??這里只允許輸入數(shù)字和符號 InputType.TYPE_NUMBER_FLAG_SIGNED

后面的設置添加intent 和點擊監(jiān)聽暫時用不到,

private fun initEditText(editText:EditTextPreference?){

? ? editText?.summaryProvider =

Preference.SummaryProvider<EditTextPreference> { 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<EditTextPreference>("preference_printserver_ip")

? ? val printip = findPreference<EditTextPreference>("preference_print_ip")

? ? val faceserverip = findPreference<EditTextPreference>("preference_faceserver_ip")

? ? initEditText(printserverip)

? ? initEditText(printip)

? ? initEditText(faceserverip)

}

四 管理您的設置

上面第二點不適用, 設置有點長,如果全部寫一個頁面里, 需要滑動,頁面底部的設置滑動上不方便,所以還是根據(jù)官網(wǎng)中把每個拆開放單獨的頁面里.

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

? ? <PreferenceCategory android:title="">

? ? ? ? <Preference

? ? ? ? ? ? ? ? android:fragment="com.insolu.insoledemo.fragment.MySetting_IP"

? ? ? ? ? ? ? ? android:title="@string/setting_ipset">

? ? ? ? </Preference>

? ? <!-- 省略 -->

? ? </PreferenceCategory>

把所有設置拆 成四個 點擊后再進入具體的設置頁面?


主要是?? android:fragment="com.insolu.insoledemo.fragment.MySetting_IP"? 指定設置頁面,具體跳轉(zhuǎn)內(nèi)部會自己管理

五 自定義您的設置

上面第三點已經(jīng)描述了寫法和作用 這里敘述下遇到的幾個問題??EditTextPreference 和 layout 中使用EditText 有些設置不一樣.比如ip 只需要數(shù)字,點 和:冒號 layout 使用?android:digits="1234567890.:" 設置就可以, 在EditTextPreference? 中沒有這個設置,文檔中讓使用inputType 但也沒有數(shù)字加符號的設置,最后是設置的 filters ,創(chuàng)建一個IpFilter類實現(xiàn)?InputFilter 接口,創(chuàng)建 一個內(nèi)部類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;

}

達到設置的目的. 網(wǎng)上搜到過類似做法.

2. 然后就是密碼 的設置 使用?edit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD .

3. 定時重啟有個時間的設置 格式要是 03:33 這種 ,做的比較暴力 直接在值修改的監(jiān)聽上,判斷新的值是否滿足 正則表達式

// 設置監(jiān)聽?

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)

}

六 使用

使用就很簡單了? ,官網(wǎng)中的代碼.

val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)val name = sharedPreferences.getString("signature", "")

七 總結

整體修改 肯定是 Preference 代碼更少, 以后維護也更方便, 最開始那種寫法 在退出設置頁面 還需要監(jiān)聽返回按鍵 退出還要把修改的項自己保存進?SharedPreferences? , 而且所有的內(nèi)容都在一個頁面,整個文件代碼也比較多,? ?以前的設置頁面代碼行數(shù)大約 720 現(xiàn)在大約? 348 .布局代碼 以前400 現(xiàn)在161 .少了很多,.

最后.? Preference 現(xiàn)在默認使用的還是?SharedPreferences? 存儲數(shù)據(jù) ,可以改為 datastore 存儲數(shù)據(jù).數(shù)據(jù)獲取變成Flow 的方式.之后整改的時候再記錄了.

datastore? 的官方鏈接 : https://developer.android.google.cn/topic/libraries/architecture/datastore?

第一次寫 多多包涵,二 三, 和四,五 ,內(nèi)容差不多,但最后沒有去整理, 因為在真實改造時候確實是按照文章的先后順序來的,當你的設置內(nèi)容少,可能二,三就完了,? 這也是改造中的一個過程,看肯定是不夠的, 希望你也可以按照官方文檔實際操作一番, 可能會發(fā)現(xiàn)對你更有用的介紹, 比如后面一些監(jiān)聽的設置. 如果你有關于文檔任何地方更好的建議或?qū)懛?可以評論告訴我. 謝謝,

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容