0

我想用饱和动画加载图像。这是 Glide、ImageView 和 ValueAnimator 有用的代码。

Glide.with(imageView)
            .asBitmap()
            .load(url)
            .transition(BitmapTransitionOptions.withCrossFade(1000))
            .apply(RequestOptions.placeholderOf(new ColorDrawable(Color.LTGRAY)))
            .listener(new RequestListener<Bitmap>() {

                @Override
                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
                    return false;
                }

                @Override
                public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
                    ValueAnimator animation = ValueAnimator.ofFloat(0F, 1F);
                    animation.setDuration(3000);
                    animation.setInterpolator(new LinearInterpolator());
                    animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator it) {
                            ColorMatrix mt = new ColorMatrix();
                            mt.setSaturation(it.getAnimatedFraction());

                            ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(mt);
                            imageView.setColorFilter(colorFilter);
                        }
                    });
                    animation.start();
                    return false;
                }

            })
            .into(imageView);

这很有用,但我想用 Jetpack Compose 和线圈来实现,我错了。这是我的代码。

var imgConfig by remember { mutableStateOf(ColorMatrix()) }

val animation = ValueAnimator.ofFloat(0F, 1F)
animation.duration = 3000
animation.addUpdateListener {
    Log.d("ValueAnimator", "new value ${it.animatedFraction}")
    imgConfig = ColorMatrix().apply {
        setToSaturation(it.animatedFraction)
    }
}
val request = ImageRequest.Builder(LocalContext.current)
    .data(url)
    .apply { this.placeholder(ColorDrawable(android.graphics.Color.LTGRAY)).crossfade(true) }
    .listener(onStart = {
        Log.d("AnimationImgLoader", "onStar");
    }, onCancel = {
        Log.d("AnimationImgLoader", "onCancel");
    }, onError = { request: ImageRequest, throwable: Throwable ->
        Log.e("AnimationImgLoader", "onError ${throwable.message}")
    }, onSuccess = { request: ImageRequest, metadata: ImageResult.Metadata ->
        Log.d("AnimationImgLoader", "onSuccess ")
        animation.start()
    })
    .build()
Image(
    painter = rememberImagePainter(request = request),
    contentDescription = "RemoteImage",
    colorFilter = ColorFilter.colorMatrix(imgConfig)
)

使用这段代码,在我的 Android Studio Logcat 中我发现太多日志是 AnimationImgLoader:onStar。

我想知道,为什么会这样?以及如何解决它。

4

1 回答 1

1

您可能应该避免将较旧的动画系统与为 Compose 设计的较新的动画系统一起使用。以下是在 Compose 中为浮动值设置动画并将其应用于图像饱和度等属性的方法:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        startActivity(intent)

        setContent {
            AnimatedImage(url = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg")
        }
    }
}


@Composable
fun AnimatedImage(
    url: String
) {
    var enabled by remember { mutableStateOf(false)}
    val saturation by animateFloatAsState(targetValue = if (enabled) 1f else 0f, animationSpec = tween(3000))

    val colorMatrix = ColorMatrix()
    colorMatrix.setToSaturation(saturation)

    val request = ImageRequest.Builder(LocalContext.current)
        .data(url)
        .apply { this.placeholder(ColorDrawable(Color.LTGRAY)).crossfade(true) }
        .listener(onStart = {
            Log.d("AnimationImgLoader", "onStar");
        }, onCancel = {
            Log.d("AnimationImgLoader", "onCancel");
        }, onError = { request: ImageRequest, throwable: Throwable ->
            Log.e("AnimationImgLoader", "onError ${throwable.message}")
        }, onSuccess = { request: ImageRequest, metadata: ImageResult.Metadata ->
            Log.d("AnimationImgLoader", "onSuccess ")
            //animation.start()
            enabled = true
        })
        .build()
    Image(
        painter = rememberImagePainter(request = request),
        contentDescription = "RemoteImage",
        colorFilter = ColorFilter.colorMatrix(colorMatrix)
    )
}
于 2021-12-01T09:05:11.383 回答