如何通过重组来阻止 AnimationDrawable 重复

问题描述 投票:0回答:1

我正在使用 accompanist-drawablepainter 在我的可组合项中显示 AnimationDrawable。 我将 Drawable 的 XML 设置为 OneShot,但如果屏幕重新组合,我的 Drawable 会再次开始动画 - 例如,在屏幕旋转后或者如果我滚动然后返回到图像。 可绘制对象根本不对 .stop() 做出反应,isRunning 始终显示 false。

我尝试在 Image 可组合项之后放置 .stop() 。 我尝试为下一个合成显示静态图像 - 为此我创建了一个布尔值来检查它是否应该动画。 问题是,isRunning 对于可绘制对象总是显示 false。 处理只应显示一次的动画可绘制对象的正确方法是什么,直到发生交互(例如按下按钮)或直到可绘制对象发生更改?

是否有更好的方法在 compose 中显示逐帧动画?不幸的是,矢量不适用于此动画。

这是我当前的代码:

@Composable
fun MainUnitCard(viewModel: HomeViewModel = viewModel()){

    val homeUiState by viewModel.uiState.collectAsState()
    val drawable = AppCompatResources.getDrawable(LocalContext.current, homeUiState.mainUnitDrawableId) as AnimationDrawable

    Card(
        onClick = {
            viewModel.updateMainUnitConnected(!homeUiState.mainUnitConnected)
        })
    {
        Column {

            Image(painter = rememberDrawablePainter(drawable = drawable, contentDescription = "")          
        }

    }
}

ViewModel 看起来像这样:

private val _onDrawable = R.drawable.anim_on
private val _offDrawable = R.drawable.anim_off

data class HomeScreenState(
    val mainUnitConnected: Boolean = false,
    val mainUnitDrawableId: Int = _offDrawable,
)

class HomeViewModel: ViewModel(){
    private val _uiState = MutableStateFlow(HomeScreenState())
    val uiState: StateFlow<HomeScreenState> = _uiState.asStateFlow()

    fun updateMainUnitConnected(connected: Boolean){
        _uiState.update {
            it.copy(
                mainUnitConnected = connected
            )
        }
        updateMainUnitDrawable(connected)
    }

    private fun updateMainUnitDrawable(connected: Boolean){
        _uiState.update {
            it.copy(
                mainUnitDrawableId = if(connected) _onDrawable else _offDrawable
            )
        }
    }
}

我也尝试过这样的事情:

@Composable
fun MainUnitCard(viewModel: HomeViewModel = viewModel()){

    val homeUiState by viewModel.uiState.collectAsState()
    val drawable = AppCompatResources.getDrawable(LocalContext.current, homeUiState.mainUnitDrawableId) as AnimationDrawable
    var animState = false

    Card(
        onClick = {
            viewModel.updateMainUnitConnected(!homeUiState.mainUnitConnected)
            animState = true
        })
    {
        Column {

            Image(painter = rememberDrawablePainter(drawable = if(animState) drawable else drawable.getFrame(39), contentDescription = "")          
        }

    }
}

但是布尔值显然永远不会存在,因此不再有动画。 我也不记得那个变量,因为我无法实际检查动画是否结束或仍在运行,至少我知道。

android kotlin android-jetpack-compose android-animation
1个回答
0
投票

您可以在布尔值上使用remember,也可以在动画本身上使用remember。来自文档

在初始合成期间,由remember计算出的值存储在Composition中,并在重新合成期间返回存储的值。

示例:

var animState = remember { false }

重组时不会重新初始化。

© www.soinside.com 2019 - 2024. All rights reserved.