繁体   English   中英

Android Jetpack Compose(可组合)手动更改触发器

[英]Android Jetpack Compose (Composable) Trigger Change Manually

我有一些自定义的可组合 animation 使用 LaunchedEffect 在 [minTemperature, maxTemperature] 范围内更改值,我想手动触发 animation。 这在我更改 minTemperature 和 maxTemperature 值时触发,所以我有LaunchedEffect(minTemperature, maxTemperature) 但问题是,只有当值更改为新值时,才会触发可变的 state。

因此,如果我调用 setTemperature() 方法,则不会触发 animation。 所以我所做的是创建新的 state 值“temperatureAnimationSwitch”,它是从 model 视图中使用公共方法 startTemperatureAnimation() 手动切换的。 所以这将触发 LaunchedEffect 的重新启动。

我的问题是:

  1. 这是使用开关值的最佳方法吗?
  2. 当 minTemperature 或 maxTemperature 值设置为之前的值时发生更改事件时,有没有办法触发 animation?
  3. 是否有类似于“状态、流、实时数据..”的 object,但它可以被触发,即使我们将其当前值更改为自身。
@HiltViewModel
class CityWeatherViewModel @Inject constructor(
    private val getCityWeather: GetCityWeather
) : ViewModel() {

    //region Temperature Component
    private val _temperatureAnimationSwitch = mutableStateOf(true)
    val temperatureAnimationSwitch: State<Boolean> = _temperatureAnimationSwitch
 
    private val _minTemperature = mutableStateOf(-22f)
    val minTemperature: State<Float> = _minTemperature

    private val _maxTemperature = mutableStateOf(12f)
    val maxTemperature: State<Float> = _maxTemperature

    fun startTemperatureAnimation() {
        _temperatureAnimationSwitch.value = !_temperatureAnimationSwitch.value
    }

    fun setTemperature(minTemperature: Float = _minTemperature.value, maxTemperature: Float = _maxTemperature.value) {
        _minTemperature.value = minTemperature
        _maxTemperature.value = maxTemperature 
    }
    //endregion
}
@Composable
fun TemperatureCanvas( 
    viewModel: CityWeatherViewModel, 
    minTemperature: Float = viewModel.minTemperature.value,
    maxTemperature: Float = viewModel.maxTemperature.value,
    temperatureAnimationSwitch: Boolean = viewModel.temperatureAnimationSwitch.value
) {

    var temperatureForText by remember { mutableStateOf(0) }
    LaunchedEffect(temperatureAnimationSwitch) {
        val animation = TargetBasedAnimation(
            animationSpec = tween(1500),
            typeConverter = Int.VectorConverter,
            initialValue = minTemperature,
            targetValue = maxTemperature
        )
        val startTime = withFrameNanos { it }
        do {
            val playTime = withFrameNanos { it } - startTime
            temperatureForText = animation.getValueFromNanos(playTime)
        } while (temperatureForText < maxTemperature)
    }
    
    // the text will be update with the animated value 'temperatureForText'
    Text(text = temperatureForText) 
}

我认为您需要将 State object 的SnapshotMutationPolicy设置为neverEqualPolicy() 这将报告对该 object 的所有写入,无论值是否更改。

    private val _minTemperature = mutableStateOf(-22f, neverEqualPolicy())
    private val _maxTemperature = mutableStateOf(12f, neverEqualPolicy())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM