Reputation: 3
I want to load image with saturation animation. Here is code useful by Glide,ImageView and 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);
It's useful, but I want to implement with Jetpack Compose and coil, I have wrong. Here this my code.
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)
)
Use this code, in my Android Studio Logcat I found too many log is AnimationImgLoader: onStar.
I want to know, why it is? And how to fix it.
Upvotes: 0
Views: 675
Reputation: 29877
You probably should avoid using the older animation system with the newer animation system designed for Compose. Here is how you animate a floating value in Compose and apply it to a property such as the image saturation:
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)
)
}
Upvotes: 1