最近需要实现一个状态管理类:
在多种场景下,控制一系列的按钮是否可操作。
随着场景数量的增加,这个管理类的实现,就可能会越来越复杂。
示例还是用大佬那个例子。
例如,存在3种模式,和3个按钮,按钮不可用的时候弹出对应的Toast。
Kotlin中的位操作
shl(bits)–左移位shr(bits)–右移位and(bits)–与or(bits)–或
定义多个十六进制的状态常量,代表不同的状态。
privateconstvalSTATE_IDIE=1privateconstvalSTATUS_A=1shl1privateconstvalSTATUS_B=1shl2privateconstvalSTATUS_C=1shl3
定义一个变量,用于存放当前的状态。
当状态发生变化,需要切换状态的时候,只需要去修改这个变量就行了。
privatevarcurrentStatus=STATE_IDIE//测试代码privatefunchangeStateToA(){changeStateToA=STATUS_A}定义多个十六进制的标志常量,代表对应的禁用操作。
比如DISABLE_BTN_1,代表禁用按钮1。
//定义不可操作的一些行为privateconstvalDISABLE_BTN_1=1shl4privateconstvalDISABLE_BTN_2=1shl5privateconstvalDISABLE_BTN_3=1shl6
定义模式状态集,由状态+多个禁用标志位组成。
比如MODE_A,就是在状态为STATUS_A的时候,按钮3禁用,那就将这两个数值进行或运算,结果就是STATUS_AorDISABLE_BTN_3。
privateconstvalMODE_A=STATUS_AorDISABLE_BTN_3privateconstvalMODE_B=STATUS_BorDISABLE_BTN_1orDISABLE_BTN_3privateconstvalMODE_C=STATUS_CorDISABLE_BTN_2orDISABLE_BTN_3privatevalmodeList=listOf(MODE_A,MODE_B,MODE_C)
key为对应状态+禁用标志位的或运算结果。这样的计算结果,是可以保证key是唯一的,不会出现重复的情况。
value为对应的Toast文案。
只需要一个HashMap就可以实现所有的配置关系。
从代码阅读性来说,使用这样的代码进行配置,看起来也比较通俗易懂。
privatevaltoastMap=hashMapOf(Pair(STATUS_AorDISABLE_BTN_3,"A3"),Pair(STATUS_BorDISABLE_BTN_1,"B1"),Pair(STATUS_BorDISABLE_BTN_3,"B3"),Pair(STATUS_CorDISABLE_BTN_2,"C2"),Pair(STATUS_CorDISABLE_BTN_3,"C3"))
核心逻辑:判断在当前模式下,按钮是否可用。
是否可用的判断:判断当前所处的状态,是否包含对应定义的禁用操作。
currentStatusandaction!=0
若可操作,返回true。
若不可操作,通过currentStatusoraction的运算结果作为key,通过上面配置的HashMap集合,拿到对应的Toast文案。
/***判断当前某个行为是否可操作**@returntrue可操作;false,不可操作。*/privatefuncheckEnable(action:Int):Boolean{valresult={(itandcurrentStatus)!=0(itandaction)!=0}if(()){println("resultisfalse,toast:${toastMap[currentStatusoraction]}")returnfalse}println("resultistrue")returntrue}完整代码
objectSixTeenTest{//定义状态常量privateconstvalSTATE_IDIE=1privateconstvalSTATUS_A=1shl1privateconstvalSTATUS_B=1shl2privateconstvalSTATUS_C=1shl3//定义不可操作的一些行为privateconstvalDISABLE_BTN_1=1shl4privateconstvalDISABLE_BTN_2=1shl5privateconstvalDISABLE_BTN_3=1shl6//定义模式状态集privateconstvalMODE_A=STATUS_AorDISABLE_BTN_3privateconstvalMODE_B=STATUS_BorDISABLE_BTN_1orDISABLE_BTN_3privateconstvalMODE_C=STATUS_CorDISABLE_BTN_2orDISABLE_BTN_3privatevalmodeList=listOf(MODE_A,MODE_B,MODE_C)//定义Toast映射关系privatevaltoastMap=hashMapOf(Pair(STATUS_AorDISABLE_BTN_3,"A3"),Pair(STATUS_BorDISABLE_BTN_1,"B1"),Pair(STATUS_BorDISABLE_BTN_3,"B3"),Pair(STATUS_CorDISABLE_BTN_2,"C2"),Pair(STATUS_CorDISABLE_BTN_3,"C3"))//当前状态privatevarcurrentStatus=STATE_IDIE/***判断当前某个行为是否可操作**@returntrue可操作;false,不可操作。*/privatefuncheckEnable(action:Int):Boolean{valresult={(itandcurrentStatus)!=0(itandaction)!=0}if(()){println("resultisfalse,toast:${toastMap[currentStatusoraction]}")returnfalse}println("resultistrue")returntrue}}代码测试funmain(args:ArrayString){//测试代码currentStatus=STATUS_Aprintln("STATUS_A")checkEnable(DISABLE_BTN_1)checkEnable(DISABLE_BTN_2)checkEnable(DISABLE_BTN_3)currentStatus=STATUS_Bprintln("STATUS_B")checkEnable(DISABLE_BTN_1)checkEnable(DISABLE_BTN_2)checkEnable(DISABLE_BTN_3)currentStatus=STATUS_Cprintln("STATUS_C")checkEnable(DISABLE_BTN_1)checkEnable(DISABLE_BTN_2)checkEnable(DISABLE_BTN_3)}输出测试结果
STATUS_Aresultistrueresultistrueresultisfalse,toast:A3STATUS_Bresultisfalse,toast:B1resultistrueresultisfalse,toast:B3STATUS_Cresultistrueresultisfalse,toast:C2resultisfalse,toast:C3十六进制
16进制多状态管理本质上是二进制管理,即‘1’所处的位数。
比如上面定义的各种变量,都是通过1左移n位数之后的结果。
这样能够保证,多个不同变量的与运算、或运算结果,可以是唯一的。比如上面,用这个特性,用来做一层Toast文案的映射关系。
总结确实,像类似的场景,随着业务迭代场景数增加,在没有使用十六进制之前,整体的代码可能是会比较复杂的。
使用十六进制之后,可能需要多花一点时间,去理解一下十六进制相关的知识,但是在代码实现上确实简单了很多。
作者:入魔的冬瓜
链接: