如何为图像设置动画 属性
How to animate an image property
我想加载带有饱和度动画的图像。这是 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和coil来实现,我错了。这是我的代码。
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工作室Logcat我发现太多日志是AnimationImgLoader: onStar。
我想知道,为什么会这样?以及如何修复它。
您可能应该避免将旧动画系统与为 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)
)
}
我想加载带有饱和度动画的图像。这是 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和coil来实现,我错了。这是我的代码。
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工作室Logcat我发现太多日志是AnimationImgLoader: onStar。
我想知道,为什么会这样?以及如何修复它。
您可能应该避免将旧动画系统与为 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)
)
}