Android?十六進(jìn)制狀態(tài)管理實(shí)例詳解
背景
最近需要實(shí)現(xiàn)一個狀態(tài)管理類:
- 在多種場景下,控制一系列的按鈕是否可操作。
- 不同場景下,在按鈕不可操作的時候,點(diǎn)擊彈出對應(yīng)的Toast。
- 隨著場景數(shù)量的增加,這個管理類的實(shí)現(xiàn),就可能會越來越復(fù)雜。
剛好看到大佬的文章,順便學(xué)習(xí)和實(shí)踐一下。
參考學(xué)習(xí):就算不去火星種土豆,也請務(wù)必掌握的 Android 狀態(tài)管理最佳實(shí)踐
示例
還是用大佬那個例子。
例如,存在 3 種模式,和 3個按鈕,按鈕不可用的時候彈出對應(yīng)的 Toast。
- 模式 A 下,要求 按鈕1、按鈕2 可用,按鈕3不可用。點(diǎn)擊按鈕3,Toast 提示“A3”。
- 模式 B 下,要求 按鈕2 可用,按鈕1和按鈕3不可用。點(diǎn)擊按鈕1,Toast 提示“B1”。點(diǎn)擊按鈕3,Toast 提示“B3”。
- 模式 C 下,要求 按鈕1 可用,按鈕2和按鈕3不可用。點(diǎn)擊按鈕2,Toast 提示“C2”。點(diǎn)擊按鈕3,Toast 提示“C3”。
實(shí)現(xiàn)思路
- Kotlin中的位操作
shl(bits) – 左移位 shr(bits) – 右移位 and(bits) – 與 or(bits) – 或
- 定義多個十六進(jìn)制的狀態(tài)常量,代表不同的狀態(tài)。
private const val STATE_IDIE = 1 private const val STATUS_A = 1 shl 1 private const val STATUS_B = 1 shl 2 private const val STATUS_C = 1 shl 3
- 定義一個變量,用于存放當(dāng)前的狀態(tài)。
- 當(dāng)狀態(tài)發(fā)生變化,需要切換狀態(tài)的時候,只需要去修改這個變量就行了。
private var currentStatus = STATE_IDIE //測試代碼 private fun changeStateToA(){ changeStateToA = STATUS_A }
- 定義多個十六進(jìn)制的標(biāo)志常量,代表對應(yīng)的禁用操作。
比如 DISABLE_BTN_1,代表禁用按鈕1。
//定義不可操作的一些行為 private const val DISABLE_BTN_1 = 1 shl 4 private const val DISABLE_BTN_2 = 1 shl 5 private const val DISABLE_BTN_3 = 1 shl 6
- 定義模式狀態(tài)集,由狀態(tài)+多個禁用標(biāo)志位組成。
比如 MODE_A,就是在狀態(tài)為 STATUS_A 的時候,按鈕3禁用,那就將這兩個數(shù)值進(jìn)行或運(yùn)算,結(jié)果就是 STATUS_A or DISABLE_BTN_3。
private const val MODE_A = STATUS_A or DISABLE_BTN_3 private const val MODE_B = STATUS_B or DISABLE_BTN_1 or DISABLE_BTN_3 private const val MODE_C = STATUS_C or DISABLE_BTN_2 or DISABLE_BTN_3 private val modeList = listOf(MODE_A, MODE_B, MODE_C)
- 定義按鈕不可點(diǎn)擊時的Toast文案 ,使用 HashMap 進(jìn)行存儲映射關(guān)系。
key 為對應(yīng)狀態(tài)+禁用標(biāo)志位的 或運(yùn)算 結(jié)果。這樣的計(jì)算結(jié)果,是可以保證key是唯一的,不會出現(xiàn)重復(fù)的情況。
value 為對應(yīng)的 Toast 文案。
只需要一個 HashMap 就可以實(shí)現(xiàn)所有的配置關(guān)系。
從代碼閱讀性來說,使用這樣的代碼進(jìn)行配置,看起來也比較通俗易懂。
比如 Pair(STATUS_A or DISABLE_BTN_3, "A3"),就是代表在狀態(tài)A的時候,禁用按鈕3,點(diǎn)擊按鈕的時候彈的Toast文案為 “A3”。
private val toastMap = hashMapOf( Pair(STATUS_A or DISABLE_BTN_3, "A3"), Pair(STATUS_B or DISABLE_BTN_1, "B1"), Pair(STATUS_B or DISABLE_BTN_3, "B3"), Pair(STATUS_C or DISABLE_BTN_2, "C2"), Pair(STATUS_C or DISABLE_BTN_3, "C3") )
- 核心邏輯:判斷在當(dāng)前模式下,按鈕是否可用。
是否可用的判斷:判斷當(dāng)前所處的狀態(tài),是否包含對應(yīng)定義的禁用操作。
currentStatus and action !=0
若可操作,返回 true。
若不可操作,通過 currentStatus or action 的運(yùn)算結(jié)果作為key,通過上面配置的 HashMap 集合,拿到對應(yīng)的 Toast 文案。
/** * 判斷當(dāng)前某個行為是否可操作 * * @return true 可操作;false,不可操作。 */ private fun checkEnable(action: Int): Boolean { val result = modeList.filter { (it and currentStatus) != 0 && (it and action) != 0 } if (result.isNotEmpty()) { println("result is false, toast:${toastMap[currentStatus or action]}") return false } println("result is true") return true }
- 完整代碼
object SixTeenTest { //定義狀態(tài)常量 private const val STATE_IDIE = 1 private const val STATUS_A = 1 shl 1 private const val STATUS_B = 1 shl 2 private const val STATUS_C = 1 shl 3 //定義不可操作的一些行為 private const val DISABLE_BTN_1 = 1 shl 4 private const val DISABLE_BTN_2 = 1 shl 5 private const val DISABLE_BTN_3 = 1 shl 6 //定義模式狀態(tài)集 private const val MODE_A = STATUS_A or DISABLE_BTN_3 private const val MODE_B = STATUS_B or DISABLE_BTN_1 or DISABLE_BTN_3 private const val MODE_C = STATUS_C or DISABLE_BTN_2 or DISABLE_BTN_3 private val modeList = listOf(MODE_A, MODE_B, MODE_C) //定義Toast映射關(guān)系 private val toastMap = hashMapOf( Pair(STATUS_A or DISABLE_BTN_3, "A3"), Pair(STATUS_B or DISABLE_BTN_1, "B1"), Pair(STATUS_B or DISABLE_BTN_3, "B3"), Pair(STATUS_C or DISABLE_BTN_2, "C2"), Pair(STATUS_C or DISABLE_BTN_3, "C3") ) //當(dāng)前狀態(tài) private var currentStatus = STATE_IDIE /** * 判斷當(dāng)前某個行為是否可操作 * * @return true 可操作;false,不可操作。 */ private fun checkEnable(action: Int): Boolean { val result = modeList.filter { (it and currentStatus) != 0 && (it and action) != 0 } if (result.isNotEmpty()) { println("result is false, toast:${toastMap[currentStatus or action]}") return false } println("result is true") return true } }
代碼測試
fun main(args: Array<String>) { //測試代碼 currentStatus = STATUS_A println("STATUS_A") checkEnable(DISABLE_BTN_1) checkEnable(DISABLE_BTN_2) checkEnable(DISABLE_BTN_3) currentStatus = STATUS_B println("STATUS_B") checkEnable(DISABLE_BTN_1) checkEnable(DISABLE_BTN_2) checkEnable(DISABLE_BTN_3) currentStatus = STATUS_C println("STATUS_C") checkEnable(DISABLE_BTN_1) checkEnable(DISABLE_BTN_2) checkEnable(DISABLE_BTN_3) }
輸出測試結(jié)果
STATUS_A
result is true
result is true
result is false, toast:A3
STATUS_B
result is false, toast:B1
result is true
result is false, toast:B3
STATUS_C
result is true
result is false, toast:C2
result is false, toast:C3
十六進(jìn)制
- 16進(jìn)制多狀態(tài)管理本質(zhì)上是二進(jìn)制管理,即‘1’所處的位數(shù)。
- 比如上面定義的各種變量,都是通過1左移n位數(shù)之后的結(jié)果。
- 這樣能夠保證,多個不同變量的與運(yùn)算、或運(yùn)算結(jié)果,可以是唯一的。比如上面,用這個特性,用來做一層 Toast 文案的映射關(guān)系。
總結(jié)
- 確實(shí),像類似的場景,隨著業(yè)務(wù)迭代場景數(shù)增加,在沒有使用十六進(jìn)制之前,整體的代碼可能是會比較復(fù)雜的。
- 使用十六進(jìn)制之后,可能需要多花一點(diǎn)時間,去理解一下十六進(jìn)制相關(guān)的知識,但是在代碼實(shí)現(xiàn)上確實(shí)簡單了很多。
以上就是Android 十六進(jìn)制狀態(tài)管理實(shí)例詳解的詳細(xì)內(nèi)容,更多關(guān)于Android 十六進(jìn)制狀態(tài)管理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android自定義viewgroup 使用adapter適配數(shù)據(jù)(6)
這篇文章主要為大家詳細(xì)介紹了Android自定義viewgroup,使用adapter適配數(shù)據(jù),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12Android實(shí)現(xiàn)圖片自動切換功能(實(shí)例代碼詳解)
這篇文章主要介紹了Android實(shí)現(xiàn)圖片自動切換功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02Android 解決ScrollView嵌套CridView顯示問題
這篇文章主要介紹了Android 解決ScrollView嵌套CridView顯示問題的相關(guān)資料,使用ScrollView嵌套CridView的時候會出現(xiàn)顯示不全的問題,這里提供解決辦法,需要的朋友可以參考下2017-08-08Android使用Pull解析器解析xml文件的實(shí)現(xiàn)代碼
Android使用Pull解析器解析xml文件的實(shí)現(xiàn)代碼,需要的朋友可以參考一下2013-02-02Android編程實(shí)現(xiàn)手機(jī)自帶內(nèi)部存儲路徑的獲取方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)手機(jī)自帶內(nèi)部存儲路徑的獲取方法,涉及Android針對掛載點(diǎn)信息的獲取技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11flutter開發(fā)技巧自定頁面指示器PageIndicator詳解
這篇文章主要為大家介紹了flutter開發(fā)技巧自定頁面指示器PageIndicator詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Android Studio 實(shí)現(xiàn)文檔注釋的快捷鍵
這篇文章主要介紹了Android Studio 實(shí)現(xiàn)文檔注釋的快捷鍵,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03