Android Jetpack Compose (Composable) запускает изменение вручную

У меня есть некоторая пользовательская составная анимация, которая изменяет значение в диапазоне [minTemperature, maxTemperature] с помощью LaunchedEffect, и я хочу запустить анимацию вручную. Это срабатывает, когда я изменяю значения minTemperature и maxTemperature, поэтому у меня есть LaunchedEffect(minTemperature, maxTemperature). Но проблема в том, что изменяемое состояние запускается ТОЛЬКО КОГДА ЗНАЧЕНИЕ ИЗМЕНЯЕТСЯ НА НОВОЕ ЗНАЧЕНИЕ.

Поэтому, если я вызову метод setTemperature(), анимация не запустится. Итак, что я сделал, так это создал новое значение состояния «temperatureAnimationSwitch», которое переключается вручную с помощью общедоступного метода startTemperatureAnimation() из модели представления. Так что это вызовет перезапуск LaunchedEffect.

Мои вопросы:

  1. Это лучший подход с использованием значения переключателя?
  2. Есть ли способ запустить анимацию, когда значения minTemperature или maxTemperature изменяются, когда установлено их предыдущее значение?
  3. Есть ли объект, похожий на «состояние, поток, livedata..», но он может запускаться, даже когда мы меняем его текущее значение на себя.
      @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) 
}

1 ответ

Я думаю, вам нужно установитьSnapshotMutationPolicyгосударства возражают противneverEqualPolicy(). Это сообщит обо всех операциях записи в этот объект, независимо от того, изменилось значение или нет.

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

Другие вопросы по тегам