Android动画Alpha

88

我有动画:

<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);

所以一开始我有一个alpha为0.2ImageView,最终我希望它的alpha为1。但事实并非如此 - 当动画开始时,会增加更多的alpha值,并且动画完成后的alpha值为0.2

我需要改变什么来使图像从0.2逐渐动画到1

我已经尝试了不同的设置 - 我设置了android:alpha="1.0"fromAlpha="1.0"toAlpha="0.2",这样就可以按照我的预期工作 - 从1的alpha值到0.2。看起来ImageView中的alpha值与动画中的alpha值相乘...


为了防止视图在结束时跳回到0.2 alpha,请使用fillAfter属性:http://developer.android.com/reference/android/view/animation/Animation.html#attr_android:fillAfter - Jave
不是这样的。Alpha值不会变成1。当我从1动画到0.2时,它可以正常工作并保持在0.2(我使用fill after)。但是当我想要从0.2动画到1时,它会淡出到接近于0,然后回到0.2。 - RCH
你是否将 fillEnabled 设置为 true? - Jave
10个回答

120

试试这个

AlphaAnimation animation1 = new AlphaAnimation(0.2f, 1.0f);
animation1.setDuration(1000);
animation1.setStartOffset(5000);
animation1.setFillAfter(true);
iv.startAnimation(animation1);

从ImageView属性中删除alpha,并从您的设备中卸载应用程序。清理、构建并重新安装。因为在我的端上它是工作的。 - Vaibhav Agarwal
我不想移除alpha - 图像应该使用alpha 0.2进行淡化处理。应用程序正在执行一些操作,当准备就绪时,我希望将我的图像动画化为alpha 1。 - RCH
请检查编辑后的代码,它在我的Google Nexus 4上运行良好。我的ImageView alpha值在开始时为0.2,但应用动画后它变为1.0,并且更改持续存在。 - Vaibhav Agarwal
1
我用了不同的方法 - 而非在布局中设置alpha或通过setAlpha/setImageAlpha设置,我在onCreate中制作了0.2->1的动画。现在当我的动画触发时,它可以完美地从0.2到1。 - RCH

57

可能有点晚了,但在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);
         }
    });

1
这就是我要找的内容。 - Radesh
非常好,谢谢!不过我想知道,.setListener(null); 会不会潜在地移除或干扰其他监听器,例如 onClick/onTouch 监听器? - Erlend K.H.

43

Kotlin 版本

只需像这样使用 ViewPropertyAnimator

iv.alpha = 0.2f
iv.animate().apply {
    interpolator = LinearInterpolator()
    duration = 500
    alpha(1f)
    startDelay = 1000
    start()
}

1
在尝试将beginDelayedTransition与ImageView.animate alpha动画混合时,这是唯一有效的解决方案。 - Coding John
3
耶!好答案!Kotlin万岁! - Oz Shabat

18

在开始动画之前将alpha设置为1对我有效:

AlphaAnimation animation1 = new AlphaAnimation(0.2f, 1.0f);
animation1.setDuration(500);
iv.setAlpha(1f);
iv.startAnimation(animation1);

至少在我的测试中,由于在动画开始之前设置透明度并不会导致闪烁。它能够正常工作。


这对我也起作用了(编辑:我的错误,我确实有XML干扰:android:alpha="0")。我会再试一下,但现在我需要它从0开始,所以现在可以使用。谢谢。 - the_dude_abides

4
这是我的扩展,这是一个使用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)
    }
}

2
"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);

2

嗯...

问题出在Android API中动画的正常操作上。

事实是,当您在代码中设置alpha值为0.2f时,它基于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值,因为您在动画中指定了0.2f作为边缘可接受值(一种最大alpha通道)。

因此,如果您想要所需的结果,则应将所有逻辑传递到代码中并在代码中操纵动画,而不是在xml中确定。

您应该了解,您的动画直接取决于两件事:

  • 动画视图的LayoutParams
  • 动画参数。

动画参数通过setFillAfter\setFillBefore方法操纵您的LayoutParams。


1
是的,你说得对。当我在我的代码中更改了起始布局参数时,它就像魔法一般好用! - user2558337

1
<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


0
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)
        }
    }
}

0
View.setOnTouchListener { v, event ->
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            v.alpha = 0f
            v.invalidate()
        }
        MotionEvent.ACTION_UP -> {
            v.alpha = 1f
            v.invalidate()


        }
    }
    false
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接