我正在使用 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 = "")
}
}
}
但是布尔值显然永远不会存在,因此不再有动画。 我也不记得那个变量,因为我无法实际检查动画是否结束或仍在运行,至少我知道。
您可以在布尔值上使用remember,也可以在动画本身上使用remember。来自文档:
在初始合成期间,由remember计算出的值存储在Composition中,并在重新合成期间返回存储的值。
示例:
var animState = remember { false }
重组时不会重新初始化。