網(wǎng)站首頁 編程語言 正文
背景
最近需要實(shí)現(xiàn)一個(gè)狀態(tài)管理類:
- 在多種場景下,控制一系列的按鈕是否可操作。
- 不同場景下,在按鈕不可操作的時(shí)候,點(diǎn)擊彈出對(duì)應(yīng)的Toast。
- 隨著場景數(shù)量的增加,這個(gè)管理類的實(shí)現(xiàn),就可能會(huì)越來越復(fù)雜。
剛好看到大佬的文章,順便學(xué)習(xí)和實(shí)踐一下。
參考學(xué)習(xí):就算不去火星種土豆,也請(qǐng)務(wù)必掌握的 Android 狀態(tài)管理最佳實(shí)踐
示例
還是用大佬那個(gè)例子。
例如,存在 3 種模式,和 3個(gè)按鈕,按鈕不可用的時(shí)候彈出對(duì)應(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) – 或
- 定義多個(gè)十六進(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
- 定義一個(gè)變量,用于存放當(dāng)前的狀態(tài)。
- 當(dāng)狀態(tài)發(fā)生變化,需要切換狀態(tài)的時(shí)候,只需要去修改這個(gè)變量就行了。
private var currentStatus = STATE_IDIE
//測試代碼
private fun changeStateToA(){
changeStateToA = STATUS_A
}
- 定義多個(gè)十六進(jìn)制的標(biāo)志常量,代表對(duì)應(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)+多個(gè)禁用標(biāo)志位組成。
比如 MODE_A,就是在狀態(tài)為 STATUS_A 的時(shí)候,按鈕3禁用,那就將這兩個(gè)數(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)擊時(shí)的Toast文案 ,使用 HashMap 進(jìn)行存儲(chǔ)映射關(guān)系。
key 為對(duì)應(yīng)狀態(tài)+禁用標(biāo)志位的 或運(yùn)算 結(jié)果。這樣的計(jì)算結(jié)果,是可以保證key是唯一的,不會(huì)出現(xiàn)重復(fù)的情況。
value 為對(duì)應(yīng)的 Toast 文案。
只需要一個(gè) HashMap 就可以實(shí)現(xiàn)所有的配置關(guān)系。
從代碼閱讀性來說,使用這樣的代碼進(jìn)行配置,看起來也比較通俗易懂。
比如 Pair(STATUS_A or DISABLE_BTN_3, "A3"),就是代表在狀態(tài)A的時(shí)候,禁用按鈕3,點(diǎn)擊按鈕的時(shí)候彈的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),是否包含對(duì)應(yīng)定義的禁用操作。
currentStatus and action !=0
若可操作,返回 true。
若不可操作,通過 currentStatus or action 的運(yùn)算結(jié)果作為key,通過上面配置的 HashMap 集合,拿到對(duì)應(yīng)的 Toast 文案。
/**
* 判斷當(dāng)前某個(gè)行為是否可操作
*
* @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)前某個(gè)行為是否可操作
*
* @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é)果。
- 這樣能夠保證,多個(gè)不同變量的與運(yùn)算、或運(yùn)算結(jié)果,可以是唯一的。比如上面,用這個(gè)特性,用來做一層 Toast 文案的映射關(guān)系。
總結(jié)
- 確實(shí),像類似的場景,隨著業(yè)務(wù)迭代場景數(shù)增加,在沒有使用十六進(jìn)制之前,整體的代碼可能是會(huì)比較復(fù)雜的。
- 使用十六進(jìn)制之后,可能需要多花一點(diǎn)時(shí)間,去理解一下十六進(jìn)制相關(guān)的知識(shí),但是在代碼實(shí)現(xiàn)上確實(shí)簡單了很多。
原文鏈接:https://juejin.cn/post/7147860255370641445
相關(guān)推薦
- 2023-04-12 如何將python代碼打包成pip包(可以pip?install)_python
- 2022-05-06 C語言基礎(chǔ)知識(shí)點(diǎn)指針的使用_C 語言
- 2022-10-30 C語言struct結(jié)構(gòu)體介紹_C 語言
- 2023-02-17 pytorch?cuda安裝報(bào)錯(cuò)的解決方法_python
- 2022-09-08 pandas庫中to_datetime()方法的使用解析_python
- 2023-01-18 python中的參數(shù)類型匹配提醒_python
- 2022-11-18 React網(wǎng)絡(luò)請(qǐng)求發(fā)起方法詳細(xì)介紹_React
- 2022-09-07 Golang使用CGO與Plugin技術(shù)運(yùn)行加載C動(dòng)態(tài)庫_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支