Issue
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.
Solution
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)
)
}
Answered By - Johann
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.