Jetpack Compose,更好的矢量翻译动画方法?较新的库无法工作

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

我的jetpack compose应用程序中有一个矢量动画,其中平移动画无限重复,并且一直运行良好,直到最近将drawablepainter更新到0.33.2(工作)与0.34.0(不工作)以及任何撰写库的某些组合1.5.4(工作)与 1.6.0(不工作)。使用较新的库,动画不会运行,仅绘制初始向量。

有没有比我在这里使用的更好的动画方法?使用较新的库组合,动画会停留在第一帧,并且似乎存在一些错误,但我无法在日志或调试中捕获任何内容。

我的代码如下

    @Composable
    fun GarageIndicatorClosing() {
        val backgroundVector =
            ImageVector.vectorResource(id = R.drawable.garage_door_open)
        val garageBackgroundPainter = rememberVectorPainter(image = backgroundVector)

        var yState by remember { mutableIntStateOf(0) }
        val yOffset = animateIntAsState(
            targetValue = yState,
            animationSpec =
            infiniteRepeatable(animation = tween(durationMillis = 1200, easing = LinearEasing))
        )
        Box {
            Image(painter = garageBackgroundPainter, contentDescription = null)
            MoveGarageArrow(yOffset = yOffset.value) {
                GarageArrow(arrowID = R.drawable.garage_door_closing_arrow_anim)
            }
        }
        yState = 150

    }

    @Composable
    fun GarageArrow(arrowID: Int) {
        Image(
            painter = painterResource(id = arrowID),
            contentDescription = null,
            contentScale = ContentScale.Crop
        )
    }

    @Composable
    fun MoveGarageArrow(
        yOffset: Int,
        item: @Composable () -> Unit
    ) {
        // outer box
        Box {
            // inner box
            Box(
                Modifier
                    .absoluteOffset(y = yOffset.dp)
                    .align(Alignment.Center)
            ) {
                item()
            }
        }
    }

带有如下所示的向量

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="200dp"
    android:height="60dp"
    android:viewportWidth="150"
    android:viewportHeight="45">
  <path
      android:pathData="M30.05,3.13 L75.8,41.88 121.55,3.13h-16L76.05,27.63 45.55,3.13Z"
      android:strokeLineJoin="miter"
      android:strokeWidth="1"
      android:fillColor="#00ff00"
      android:strokeColor="#ffffff"
      android:strokeLineCap="butt"/>
</vector>

下面是我可以使用的最新库集,并且仍然可以使用矢量动画。

使用 1.6.0 compose 库或drawablepainter 33.2 或更高版本的任意组合会中断动画

dependencies {
    implementation "androidx.activity:activity-compose:1.8.2"
    implementation "androidx.car.app:app:1.2.0"
    implementation "androidx.compose.animation:animation-graphics:1.5.4" // any 1.6.0 breaks as well
    implementation "androidx.compose.foundation:foundation:1.5.4"
    implementation "androidx.compose.ui:ui-tooling-preview:1.5.4"
    implementation "androidx.compose.material3:material3:1.1.2"
    implementation "androidx.constraintlayout:constraintlayout:2.1.4"
    implementation "androidx.core:core-ktx:1.12.0"
    implementation "androidx.preference:preference-ktx:1.2.1"
    implementation "androidx.work:work-runtime-ktx:2.9.0"
    implementation "com.android.volley:volley:1.2.1"
    implementation 'com.google.accompanist:accompanist-drawablepainter:0.33.1-alpha' //33.2 breaks
    implementation "com.google.android.gms:play-services-location:21.1.0"
    api 'com.google.android.material:material:1.11.0'
    implementation 'com.google.code.gson:gson:2.10.1'

    apply plugin: 'com.google.gms.google-services'
    debugImplementation 'androidx.compose.ui:ui-tooling:1.5.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
}

我有一个最小的项目来说明这个问题,网址为https://github.com/coinzdude/AnimationBug/tree/master

工作动画看起来像这样

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

我发现了一些可以与旧库和新库配合良好的东西。有两个需要改变的地方。重要且实际的修复可能就是下面的#2。

  1. 切换到使用带有触发变量的“animateDpAsState”,例如'doorState',启动动画/状态更改
  2. 在单独的线程中更改要更改的触发变量。如果在同一可组合线程中更改状态变量,我无法启动动画。使用具有延迟的 LaunchedEffect 可以实现这一点,我可以在原始可组合实例化中初始化状态变量后更改状态变量。这很重要,因为我总是希望在绘制该图像时显示动画,因为它不是用户启动的。
    @Composable
    fun GarageIndicatorOpening() {
        var doorState by remember { mutableStateOf(DoorPosition.Start) }
        val offsetAnimation: Dp by animateDpAsState(
            if (doorState == DoorPosition.Start) 150.dp else 0.dp,
            infiniteRepeatable(animation = tween(durationMillis = 1200, easing = LinearEasing), repeatMode = RepeatMode.Restart),
            label = "Door"
        )
        val backgroundVector =
            ImageVector.vectorResource(id = R.drawable.garage_door_action_background)
        val garageBackgroundPainter = rememberVectorPainter(image = backgroundVector)

        Box {
            Image(painter = garageBackgroundPainter, contentDescription = null)
            MoveGarageArrow(yOffset = offsetAnimation) {
                GarageArrow(arrowID = R.drawable.garage_door_opening_arrow_anim)
            }
        }
        LaunchedEffect(Unit) {
            delay(1.milliseconds)
            doorState = DoorPosition.Finish
        }
    }

为了完整起见,MoveGarageArrow 略有更改以接受新的 Dp 参数与 int

    @Composable
    fun MoveGarageArrow(
        yOffset: Dp,
        item: @Composable () -> Unit
    ) {
        // outer box
        Box {
            // inner box
            Box(
                Modifier
                    .absoluteOffset(y = yOffset)
                    .align(Alignment.Center)
            ) {
                item()
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.