前言
组件触发重新渲染需要满足两个前提
- 变量是
mutableState
,并且发生改变 - 组件内部使用到了这值
讲解
问题示例
先看一个示例
这个示例会有问题,当拖动的时候不会渲染,只有拖动结束才会渲染。
1 | import android.annotation.SuppressLint |
解决方式1
这个在拖动的时候不会渲染,是因为currentPath是个对象,对象的指向没有变化,所以不会被监听到变化。
只要修改这里就能触发渲染
1 | onDrag = { change, _ -> |
解决方式2
1 | import android.annotation.SuppressLint |
我们也可以新增一个变量来触发渲染。
注意
虽然组件内不需要,也要在组件内使用
drawConunter
,否则不会触发渲染。
当然这样也行
1 | import android.annotation.SuppressLint |
我们把var drawConunter by remember { mutableIntStateOf(0) }
更换为了val drawConunter = remember { mutableIntStateOf(0) }
组件内也必须是drawConunter.value
,否则不会渲染
区别
那么var drawConunter by remember { mutableIntStateOf(0) }
和val drawConunter = remember { mutableIntStateOf(0) }
有什么区别呢?
1 | var drawCounter by remember { mutableIntStateOf(0) } |
写法1
var drawCounter by remember { mutableIntStateOf(0) }
这种写法使用了 Kotlin 的委托属性(delegated properties)特性。
mutableIntStateOf(0)
会创建一个 MutableState<Int>
对象,而 by
关键字则将 drawCounter
委托给这个 MutableState<Int>
对象。
代码示例
1 | import androidx.compose.runtime.getValue |
解释
使用方式:当你使用
drawCounter
时,实际上是在调用MutableState
对象的getValue()
和setValue()
方法。当你给
drawCounter
赋值时,会调用setValue()
方法更新状态;当你读取drawCounter
的值时,会调用getValue()
方法获取状态的值。Compose 中的应用:在 Jetpack Compose 里,这种方式非常有用,因为 Compose 可以自动追踪
MutableState
的变化,并在状态改变时重新组合受影响的部分。例如,当
drawCounter
的值改变时,Compose 会知道状态有更新,进而重新执行依赖于drawCounter
的组合函数。
写法2
var drawCounter = remember { mutableIntStateOf(0) }
这种写法只是简单地将 mutableIntStateOf(0)
返回的 MutableState<Int>
对象赋值给 drawCounter
变量。
代码示例
1 | import androidx.compose.runtime.mutableIntStateOf |
解释
使用方式:要访问或修改状态的值,你需要显式地使用
drawCounter.value
。因为
drawCounter
现在是一个MutableState<Int>
对象,而不是一个简单的Int
类型变量。Compose 中的应用:虽然
MutableState
仍然可以被 Compose 追踪,但在使用时会更繁琐,因为每次访问或修改状态值都要带上.value
,而且代码的可读性也会降低。
总结
在 Jetpack Compose 中,通常推荐使用 var drawCounter by remember { mutableIntStateOf(0) }
这种写法,因为它更简洁,使用起来更自然,并且能让 Compose 更方便地追踪状态变化,从而实现自动重新组合。