当前位置 : 主页 > 手机开发 > android >

Android 十六进制状态管理实例详解

来源:互联网 收集:自由互联 发布时间:2023-02-01
目录 背景 示例 实现思路 代码测试 十六进制 总结 背景 最近需要实现一个状态管理类: 在多种场景下,控制一系列的按钮是否可操作。 不同场景下,在按钮不可操作的时候,点击弹出
目录
  • 背景
    • 示例
  • 实现思路
    • 代码测试
      • 十六进制
        • 总结

          背景

          最近需要实现一个状态管理类:

          • 在多种场景下,控制一系列的按钮是否可操作。
          • 不同场景下,在按钮不可操作的时候,点击弹出对应的Toast。
          • 随着场景数量的增加,这个管理类的实现,就可能会越来越复杂。

          刚好看到大佬的文章,顺便学习和实践一下。
          参考学习:就算不去火星种土豆,也请务必掌握的 Android 状态管理最佳实践

          示例

          还是用大佬那个例子。

          例如,存在 3 种模式,和 3个按钮,按钮不可用的时候弹出对应的 Toast。

          • 模式 A 下,要求 按钮1、按钮2 可用,按钮3不可用。点击按钮3,Toast 提示“A3”。
          • 模式 B 下,要求 按钮2 可用,按钮1和按钮3不可用。点击按钮1,Toast 提示“B1”。点击按钮3,Toast 提示“B3”。
          • 模式 C 下,要求 按钮1 可用,按钮2和按钮3不可用。点击按钮2,Toast 提示“C2”。点击按钮3,Toast 提示“C3”。

          实现思路

          • Kotlin中的位操作
          shl(bits) – 左移位 
          shr(bits) – 右移位
          and(bits) – 与 
          or(bits) – 或 
          
          • 定义多个十六进制的状态常量,代表不同的状态。
              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 var currentStatus = STATE_IDIE
              //测试代码
              private fun changeStateToA(){
                      changeStateToA = STATUS_A
              }
          
          • 定义多个十六进制的标志常量,代表对应的禁用操作。
            比如 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
          
          • 定义模式状态集,由状态+多个禁用标志位组成。
            比如 MODE_A,就是在状态为 STATUS_A 的时候,按钮3禁用,那就将这两个数值进行或运算,结果就是 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)
          
          • 定义按钮不可点击时的Toast文案 ,使用 HashMap 进行存储映射关系。

          key 为对应状态+禁用标志位的 或运算 结果。这样的计算结果,是可以保证key是唯一的,不会出现重复的情况。

          value 为对应的 Toast 文案。

          只需要一个 HashMap 就可以实现所有的配置关系。

          从代码阅读性来说,使用这样的代码进行配置,看起来也比较通俗易懂。
          比如 Pair(STATUS_A or DISABLE_BTN_3, "A3"),就是代表在状态A的时候,禁用按钮3,点击按钮的时候弹的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")
              )
          
          • 核心逻辑:判断在当前模式下,按钮是否可用。
            是否可用的判断:判断当前所处的状态,是否包含对应定义的禁用操作。
          currentStatus and action !=0
          

          若可操作,返回 true。

          若不可操作,通过 currentStatus or action 的运算结果作为key,通过上面配置的 HashMap 集合,拿到对应的 Toast 文案。

              /**
               * 判断当前某个行为是否可操作
               *
               * @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 {
              //定义状态常量
              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
              //定义模式状态集
              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映射关系
              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")
              )
              //当前状态
              private var currentStatus = STATE_IDIE
              /**
              * 判断当前某个行为是否可操作
               *
               * @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)
              }
          

          输出测试结果

          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

          十六进制

          • 16进制多状态管理本质上是二进制管理,即‘1’所处的位数。
          • 比如上面定义的各种变量,都是通过1左移n位数之后的结果。
          • 这样能够保证,多个不同变量的与运算、或运算结果,可以是唯一的。比如上面,用这个特性,用来做一层 Toast 文案的映射关系。

          总结

          • 确实,像类似的场景,随着业务迭代场景数增加,在没有使用十六进制之前,整体的代码可能是会比较复杂的。
          • 使用十六进制之后,可能需要多花一点时间,去理解一下十六进制相关的知识,但是在代码实现上确实简单了很多。

          以上就是Android 十六进制状态管理实例详解的详细内容,更多关于Android 十六进制状态管理的资料请关注自由互联其它相关文章!

          上一篇:Android IdleHandler基本使用及应用案例详解
          下一篇:没有了
          网友评论