我有动画:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator">
<alpha
android:fromAlpha="0.2"
android:toAlpha="1.0"
android:duration="500"/>
</set>
和ImageView
:
<ImageView
android:id="@+id/listViewIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/settings"
android:alpha="0.2"/>
和代码:
final Animation anim = AnimationUtils.loadAnimation(this, R.anim.alpha);
final ImageView iv = (ImageView) findViewById(R.id.listViewIcon);
anim .setFillAfter(true);
iv.startAnimation(anim);
所以一开始我有ImageView
和α0.2
,最后我想有ImageView
和α1
。但它并不是这样工作的——当动画开始时,添加了更多的alpha,动画结束时使用alpha 0.2
从0.2
到1
,我必须更改什么才能对图像进行动画处理?
我检查了不同的设置——我设置了android:alpha="1.0"
、fromAlpa="1.0"
、toAlpha="0.2"
——它的工作原理与我预期的一样——从alpha 1
到0.2
。看起来ImageView
中的alpha与动画中的alpha相乘。。。
试试这个
AlphaAnimation animation1 = new AlphaAnimation(0.2f, 1.0f);
animation1.setDuration(1000);
animation1.setStartOffset(5000);
animation1.setFillAfter(true);
iv.startAnimation(animation1);
可能有点晚了,但在android文档中找到了一个不错的解决方案。
//In transition: (alpha from 0 to 0.5)
view.setAlpha(0f);
view.setVisibility(View.VISIBLE);
view.animate()
.alpha(0.5f)
.setDuration(400)
.setListener(null);
//Out transition: (alpha from 0.5 to 0)
view.setAlpha(0.5f)
view.animate()
.alpha(0f)
.setDuration(400)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
view.setVisibility(View.GONE);
}
});
•Kotlin Version
只需像这样使用ViewPropertyAnimator
:
iv.alpha = 0.2f
iv.animate().apply {
interpolator = LinearInterpolator()
duration = 500
alpha(1f)
startDelay = 1000
start()
}
在开始动画之前将alpha设置为1
对我有效:
AlphaAnimation animation1 = new AlphaAnimation(0.2f, 1.0f);
animation1.setDuration(500);
iv.setAlpha(1f);
iv.startAnimation(animation1);
至少在我的测试中,因为在开始动画之前设置了alpha,所以没有闪烁。它只是工作得很好。
这是我的扩展,这是一个使用FadIn和FadOut更改图像的示例:
fun ImageView.setImageDrawableWithAnimation(@DrawableRes() resId: Int, duration: Long = 300) {
if (drawable != null) {
animate()
.alpha(0f)
.setDuration(duration)
.withEndAction {
setImageResource(resId)
animate()
.alpha(1f)
.setDuration(duration)
}
} else if (drawable == null) {
setAlpha(0f)
setImageResource(resId)
animate()
.alpha(1f)
.setDuration(duration)
}
}
嗯。。。
事情是错误的,并且可能在Android API中动画的正确操作中。
事实是,当你在代码中设置0.2f的alpha值是基于android的xml文件中的设置时,这意味着:
0.2f = 0.2f of 0.2f (20% from 100%) ie from 0.2f / 5 = 0.04f
1f = 0.2f
所以你的动画实际上可以从0.04f到0.2f
标志setFillAfter(true)
当然有效,但您需要明白,在动画结束时,ImageView
将具有0.2f的alpha值,而不是1,因为您在动画中指定0.2f为可接受的边缘值(一种最大alpha通道)。
因此,如果你想得到想要的结果,你应该把所有的逻辑都带到你的代码中,并在代码中操纵动画,而不是在xml中确定。
你应该明白,你的动画直接取决于两件事:
- 动画视图的布局参数
- 动画参数
动画参数在setFillAfter\setFillBefore方法中操纵LayoutParams。
"setStartOffset
"应该更小,否则动画从视图alpha 0.xf
开始,等待开始偏移,然后再动画到1f
。希望以下代码能有所帮助。
AlphaAnimation animation1 = new AlphaAnimation(0.1f, 1f);
animation1.setDuration(1000);
animation1.setStartOffset(50);
animation1.setFillAfter(true);
view.setVisibility(View.VISIBLE);
view.startAnimation(animation1);
<ImageView
android:id="@+id/listViewIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/settings"/>
从XML->ImageView中删除android:alpha=0.2
。
View.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
v.alpha = 0f
v.invalidate()
}
MotionEvent.ACTION_UP -> {
v.alpha = 1f
v.invalidate()
}
}
false
}
fun View.toggleAlpha(isShow: Boolean, delay: Long = 200, invisibleMode: Int = View.GONE) {
if (isShow) animateAlpha(View.VISIBLE, delay) else animateAlpha(invisibleMode, delay)
}
fun View.animateAlpha(visibility: Int, delay: Long = 200) {
if (visibility == View.VISIBLE) {
setVisibility(View.VISIBLE)
}
val alpha = when (visibility) {
View.GONE, View.INVISIBLE -> 0f
View.VISIBLE -> 1f
else -> 1f
}
animate().apply {
duration = delay
alpha(alpha)
withEndAction {
setVisibility(visibility)
}
}
}