1- # StateMachine 状态机在下拉刷新控件库中的使用
1+ # 状态机( StateMachine)在下拉刷新控件库中的使用
22
3- 文中提到的状态机均为有限状态机
4-
5- ` 3bdfc4c8 ` 提交中引入状态机重新实现了控件下拉刷新中的状态转换逻辑
3+ 文中提到的状态机均为有限状态机(FSM)
64
75### 背景
86
97- 状态转换,状态判断逻辑复杂
108
11- 代码中定义了4个下拉刷新的状态以及可以影响刷新状态的其他变量,在手势事件,嵌套滑动,自动刷新等事件的输入情况下,需要对几个变量进行正确判断,才能做出响应。不宜上手,维护成本较高 。
9+ 代码中定义了4个下拉刷新的状态以及可以影响刷新状态的其他变量,在手势事件,嵌套滑动,自动刷新等事件的输入情况下,需要对几个变量进行正确判断,再做出响应 。
1210
1311``` kotlin
1412private fun updatePos (change : Int ) {
1513 .. .
16- // 转换状态的同时,还需要进行状态的判断
14+ // 转换状态的同时,需要进行状态的判断
1715 // leave initiated position or just refresh complete
1816 if (mPtrStateController!! .hasJustLeftStartPosition() && mStatus == PTR_STATUS_INIT ) {
1917 changeStatusTo(PTR_STATUS_PREPARE )
@@ -34,7 +32,7 @@ private fun updatePos(change: Int) {
3432事件产生,状态检查,状态转换,触发动作的代码都耦合在一起。给代码理解,debug,修复问题都增加了障碍。
3533
3634
37- - 由于判断逻辑复杂,可读性变差,冗余方法来让代码的可读性更强
35+ - 由于判断逻辑复杂,可读性变差,冗余方法来让代码的可读性更好
3836
3937```
4038/**
@@ -64,7 +62,7 @@ private fun tryScrollBackToTopAbortRefresh() {
6462并且让代码简洁,可维护性高?
6563
6664在思考这个问题的时候,我就想到游戏开发,他们如何在多个玩家进行大量的位移,技能释放等多种事件输入的场景下来保证逻辑正常运转的。如果只是靠简单的if,else判断,那对维护者来说,绝对是个灾难。
67- 随即,我看到了游戏开发中对状态机使用的一些文章。觉得同样适用在下拉刷新中 。
65+ 随即,我看到了游戏开发中对状态机使用的一些文章。觉得状态机同样适用在下拉刷新库中 。
6866
6967### 什么是状态机
7068
@@ -81,10 +79,12 @@ private fun tryScrollBackToTopAbortRefresh() {
8179- 动作(Action/SideEffect):表示在给定时刻要进行的活动。
8280- 事件(Event):事件通常会引起状态的变迁,促使状态机从一种状态切换到另一种状态。
8381
84- ### 引入后的效果
85- 幸运的是,kotlin社区已经有了状态机的[ 开源实现] ( https://github.com/Tinder/StateMachine )
82+ ### 引入状态机
83+ 幸运的是,Kotlin社区已经有了状态机的[ 开源实现] ( https://github.com/Tinder/StateMachine )
84+
85+ [ 3bdfc4c8] ( https://github.com/s1rius/android-nest-scroll-ptr/commit/3bdfc4c8e3d64d79d0f995a3f28c577db66f27ac ) 提交中引入状态机重新实现了控件下拉刷新中的状态转换逻辑
8686
87- 重新梳理的下拉刷新的逻辑,我们发现, 下拉刷新的状态可以简化为3个
87+ 重新梳理的下拉刷新的逻辑,下拉刷新的状态可以简化为3个
8888
8989``` kotlin
9090sealed class State {
@@ -146,41 +146,23 @@ var stateMachine =
146146 transitionTo(State .REFRESHING , SideEffect .OnRefreshing )
147147 }
148148 }
149-
149+
150+ // 刷新状态
150151 state<State .REFRESHING > {
151- on<Event .RefreshComplete > {
152- transitionTo(State .IDLE , SideEffect .OnComplete )
153- }
154- on<Event .ReleaseToIdle > {
155- transitionTo(State .IDLE , SideEffect .OnComplete )
156- }
152+ // 定义刷新状态下事件触发产生的状态转移
153+ .. .
157154 }
158155
156+ // 拖动状态
159157 state<State .DRAG > {
160- on<Event .ReleaseToIdle > {
161- transitionTo(State .IDLE , SideEffect .OnCancelToIdle )
162- }
163- on<Event .ReleaseToRefreshing > {
164- transitionTo(State .REFRESHING , SideEffect .OnRefreshing )
165- }
166- on<Event .RefreshComplete > {
167- transitionTo(State .IDLE , SideEffect .OnComplete )
168- }
158+ // 定义拖动状态下事件触发产生的状态转移
159+ .. .
169160 }
170161
171162 onTransition {
172163 val validTransition = it as ? StateMachine .Transition .Valid ? : return @onTransition
173164 when (validTransition.sideEffect) {
174- SideEffect .OnDragBegin -> { }
175- SideEffect .OnComplete -> {
176- // complete
177- }
178- SideEffect .OnRefreshing -> {
179- // refresh
180- }
181- SideEffect .OnCancelToIdle -> {
182- // back to init
183- }
165+ // 执行状态转移时对应的动作
184166 }
185167 }
186168 }
@@ -191,21 +173,21 @@ var stateMachine =
1911731 . 现在的由于状态转换的触发逻辑,都在` onTransition ` 的lambda中统一处理,简单易懂
192174
193175 ```
194- when (validTransition.sideEffect) {
176+ when (validTransition.sideEffect) {
195177 SideEffect.OnDragBegin -> { }
196178 SideEffect.OnComplete -> {
197- // complete
179+ // 执行刷新完成的总做
198180 }
199181 SideEffect.OnRefreshing -> {
200- // refresh
182+ // 执行刷新动作
201183 }
202184 SideEffect.OnCancelToIdle -> {
203- // back to init
185+ // 执行回到顶部的动作
204186 }
205187 }
206188 ```
207189
208- 2. 通过Event触发状态的转换,开发者只需要关心,事件的触发是否合理
190+ 2. 通过Event触发状态的转换,触发事件时不需要对状态进行判断,因为状态转换的判断都已经在状态机的内部完成
209191
210192 ```
211193 // 触发下拉事件
@@ -228,4 +210,10 @@ var stateMachine =
228210
229211### 结论
230212
231- 引入状态机后,抽象程度提高,代码逻辑变简洁。和原来相比更容易阅读和维护了。
213+ 引入状态机后,抽象程度提高,代码逻辑变简洁。和原来相比更容易阅读和维护了。
214+
215+
216+ ##### 参考
217+ 1. [有限状态机](https://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA)
218+ 2. [趣说游戏AI开发:对状态机的褒扬和批判](https://zhuanlan.zhihu.com/p/20476688)
219+ 3. [Unity 教程 | 状态机 1](https://www.bilibili.com/video/BV1St4y1Y7U1)
0 commit comments