例如:
我有一个红色背景的视图。视图的背景颜色变为蓝色。如何在颜色之间进行平滑过渡?
如果无法通过视图完成操作,将欢迎使用其他替代方法。
#1 楼
我最终找到了解决这个问题的(相当不错的)解决方案!您可以使用TransitionDrawable来完成此任务。例如,在drawable文件夹中的XML文件中,您可以编写以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
<item android:drawable="@drawable/original_state" />
<item android:drawable="@drawable/new_state" />
</transition>
然后,在XML中获取实际视图,您可以在
android:background
属性。此时,您可以执行以下命令在代码中启动过渡:
TransitionDrawable transition = (TransitionDrawable) viewObj.getBackground();
transition.startTransition(transitionTime);
或在反向调用:
transition.reverseTransition(transitionTime);
有关使用Property Animation API的另一种解决方案,请参阅Roman的答案,该解决方案最初发布时尚不可用。
评论
谢谢mxrider!这确实回答了问题。不幸的是,它对我不起作用,因为以TransitionDrawable为背景的视图也必须进行动画处理,并且似乎该视图动画会覆盖背景过渡。有任何想法吗?
–hpique
2010年7月9日在20:36
通过在开始动画后启动TransitionDrawable来解决它。
–hpique
2010年7月9日21:00
太棒了!真高兴你做到了!您可以在Android的xml中完成很多很酷的工作-其中很多都隐藏在文档中,在我看来并不明显。
–偶像化
2010年7月10日在4:28
一点都不明显。我应该提到的是,由于颜色是动态的,因此我不使用xml。如果您通过代码创建TransitionDrawable,则您的解决方案也将起作用。
–hpique
2010年7月10日在9:43
主要缺点之一是没有动画完整的侦听器
– Leo Droidcoder
18年8月16日在9:49
#2 楼
您可以使用新的Property Animation Api进行彩色动画:int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(250); // milliseconds
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
textView.setBackgroundColor((int) animator.getAnimatedValue());
}
});
colorAnimation.start();
为了向后兼容Android 2.x,请使用Jake Wharton的Nine Old Androids库。 在Android M中已弃用
getColor
方法,因此您有两种选择:如果使用支持库,则需要替换
getColor
调用使用:ContextCompat.getColor(this, R.color.red);
如果不使用支持库,则需要将
getColor
调用替换为:getColor(R.color.red);
评论
如果您使用的是Property Animation API(或NineOldAndroid),则为“ musthave”解决方案。动画非常流畅。
–德米特里·扎伊采夫(Dmitry Zaytsev)
2014年2月6日15:04
有什么办法可以这样设置过渡的持续时间吗?
– iGio90
2014年3月22日在17:29
@ iGio90是的,您不会相信它,但是方法调用setDuration():)
–罗马Minenok
2014年5月2日19:10
ValueAnimator.ofArgb(colorFrom,colorTo)看起来更准确,但是很遗憾,它是新的。
– TWiStErRob
16-3-29在11:37
美丽的解决方案!谢谢。
–史蒂夫·弗利(Steve Folly)
16年8月3日,12:32
#3 楼
根据视图获取背景颜色和目标颜色的方式,有几种不同的实现方法。前两种使用Android Property Animation框架。
在以下情况下使用对象动画器:
您的视图的背景色定义为xml文件中的
argb
值。您的视图先前的颜色由
view.setBackgroundColor()
设置您的视图的背景色在可绘制对象中定义,没有定义任何额外的属性,例如笔触或转角半径。
您的视图的背景色在可绘制对象中定义,您要删除任何额外的属性(例如笔触或拐角半径),请记住,移除多余的属性不会设置动画。 ,这很少。这意味着将删除可绘制对象中任何多余的背景属性(例如笔触或拐角)。
如果出现以下情况,请使用Value Animator:
您的视图具有背景色在可绘制的图形中定义,该图形也设置了笔触或拐角半径等属性,并且您希望将其更改为在运行时确定的新颜色。 />
您的视图应在部署之前定义的两个可绘制对象之间切换。能够解决问题,因此,如果遇到任何意外的卡顿,您可能会遇到与我相同的错误。
如果要使用StateLists可绘制对象或LayerLists可绘制对象,则必须修改Value Animator示例,否则它将在
view.setBackgroundColor
行上崩溃。Object Animator:
视图定义:
<View
android:background="#FFFF0000"
android:layout_width="50dp"
android:layout_height="50dp"/>
创建并使用这样的
ColorDrawable
。final ObjectAnimator backgroundColorAnimator = ObjectAnimator.ofObject(view,
"backgroundColor",
new ArgbEvaluator(),
0xFFFFFFFF,
0xff78c5f9);
backgroundColorAnimator.setDuration(300);
backgroundColorAnimator.start();
您还可以使用AnimatorInflater从xml中加载动画定义,就像XMight在Android object中所做的那样。Animate动画布局的backgroundColor
Value Animator: br />
<View
android:background="@drawable/example"
android:layout_width="50dp"
android:layout_height="50dp"/>
可绘制的定义:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<stroke
android:color="#edf0f6"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
创建并使用ValueAnimator如下:
final ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(),
0xFFFFFFFF,
0xff78c5f9);
final GradientDrawable background = (GradientDrawable) view.getBackground();
currentAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(final ValueAnimator animator) {
background.setColor((Integer) animator.getAnimatedValue());
}
});
currentAnimation.setDuration(300);
currentAnimation.start();
可绘制过渡图:
视图定义:
<View
android:background="@drawable/example"
android:layout_width="50dp"
android:layout_height="50dp"/>
可绘制定义:
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#FFFFFF"/>
<stroke
android:color="#edf0f6"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
</item>
<item>
<shape>
<solid android:color="#78c5f9"/>
<stroke
android:color="#68aff4"
android:width="1dp"/>
<corners android:radius="3dp"/>
</shape>
</item>
</transition>
像这样使用TransitionDrawable: />
还有其他制作动画的方法,但这三种可能是最常见的。我通常使用ValueAnimator。
评论
实际上,可以在代码中定义和使用TransitionDrawable,但是由于某种原因,它第二次不起作用。奇怪的。
– Android开发人员
2014年4月30日在8:31
即使我的视图设置了ColorDrawable,我也可以使用对象动画器。我只是将其保存到局部变量,将其设置为null,然后在完成动画后,将原始ColorDrawable设置回去。
–MilošČernilovský
15年7月21日在13:13
#4 楼
您可以使对象成为动画师。例如,我有一个targetView,我想更改您的背景色:int colorFrom = Color.RED;
int colorTo = Color.GREEN;
int duration = 1000;
ObjectAnimator.ofObject(targetView, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo)
.setDuration(duration)
.start();
评论
在API 21中,您可以使用ofArgb(targetView,“ backgroundColor”,colorFrom,colorTo)。它的实现只是ofInt(...)。setEvaluator(new ArgbEvaluator())。
– ypresto
16年8月9日在5:10
#5 楼
如果您想要这样的彩色动画,此代码将帮助您:
评论
初始化anim变量的部位在哪里?
–VoW
16年8月22日在18:26
@VoW,它只是ValueAnimator的实例。
– RBK
18年4月24日在9:16
它应该是anim.setRepeatCount(ValueAnimator.INFINITE);现在不是Animation.INFINITE,还是一样,但我们无法保证
– MikhailKrishtop
18-10-4在12:50
@MikhailKrishtop Animation.INFINITE有什么问题? developer.android.com/reference/android/view/animation/…
– RBK
18-10-5在7:05
#6 楼
最好的方法是使用ValueAnimator和ColorUtils.blendARGB
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
valueAnimator.setDuration(325);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float fractionAnim = (float) valueAnimator.getAnimatedValue();
view.setBackgroundColor(ColorUtils.blendARGB(Color.parseColor("#FFFFFF")
, Color.parseColor("#000000")
, fractionAnim));
}
});
valueAnimator.start();
#7 楼
实现此目的的另一种简便方法是使用AlphaAnimation执行淡入。 br />为孩子提供与容器相同的背景将容器的背景更改为目标颜色
使用AlphaAnimation淡出孩子。
动画完成后删除孩子(使用AnimationListener)
#8 楼
有关XML驱动的动画的文档太可怕了。我搜索了大约几个小时,只是为了在按下按钮时设置按钮的背景色的动画...可悲的是,动画只是一个属性而已:您可以在exitFadeDuration
中使用selector
: pre class =“ lang-xml prettyprint-override”> <selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="200">
<item android:state_pressed="true">
<shape android:tint="#3F51B5" />
</item>
<item>
<shape android:tint="#F44336" />
</item>
</selector>
然后就可以将其用作
background
。无需Java / Kotlin代码。评论
极好的答案。请注意,您可能还需要android:enterFadeDuration;我的经验是,没有它,我的动画第二次将无法正常运行。
–字符串
2月13日18:38
#9 楼
这是我在基本练习中用于更改背景的方法。我正在使用通过代码生成的GradientDrawables,但是可以进行调整以适应。使用
setCrossFadeEnabled(true)
的Android <4.3会导致不良的泛白效果,因此必须使用上述@Roman Minenok ValueAnimator方法将<4.3切换为纯色。 评论
这正是我想要的。谢谢! :)
–cyph3r
2014年7月10日20:50
#10 楼
答案有很多方式。您也可以使用ofArgb(startColor,endColor)
中的ValueAnimator
。 用于API> 21:
int cyanColorBg = ContextCompat.getColor(this,R.color.cyan_bg);
int purpleColorBg = ContextCompat.getColor(this,R.color.purple_bg);
ValueAnimator valueAnimator = ValueAnimator.ofArgb(cyanColorBg,purpleColorBg);
valueAnimator.setDuration(500);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
relativeLayout.setBackgroundColor((Integer)valueAnimator.getAnimatedValue());
}
});
valueAnimator.start();
#11 楼
这是一个不错的功能,它可以实现以下功能:public static void animateBetweenColors(final @NonNull View viewToAnimateItsBackground, final int colorFrom,
final int colorTo, final int durationInMs) {
final ColorDrawable colorDrawable = new ColorDrawable(durationInMs > 0 ? colorFrom : colorTo);
ViewCompat.setBackground(viewToAnimateItsBackground, colorDrawable);
if (durationInMs > 0) {
final ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.addUpdateListener(animator -> {
colorDrawable.setColor((Integer) animator.getAnimatedValue());
ViewCompat.setBackground(viewToAnimateItsBackground, colorDrawable);
});
colorAnimation.setDuration(durationInMs);
colorAnimation.start();
}
}
在科特林:
评论
这不支持低端版本的手机
– Kartheek s
2014年7月5日在5:12
@Kartheeks您的意思是Android 10及更低版本?如果是这样,您可以轻松使用“ nineOldAndroids”库来支持它:nineoldandroids.com。语法几乎完全相同。
– Android开发人员
2014年7月5日在8:20
较低版本的colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){@Override public void onAnimationUpdate(ValueAnimator animation){colorDrawable.setColor((Integer)animation.getAnimatedValue()); ViewCompat.setBackground(viewToAnimateItsBackground,colorDrawable);}}) ;
– Mahbubur Rahman Khan
3月21日21:22
#12 楼
将文件夹动画制作者添加到res文件夹中。 (名称必须是动画师)。添加动画师资源文件。例如res / animator / fade.xml<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:propertyName="backgroundColor"
android:duration="1000"
android:valueFrom="#000000"
android:valueTo="#FFFFFF"
android:startOffset="0"
android:repeatCount="-1"
android:repeatMode="reverse" />
</set>
内部活动Java文件,将其称为
View v = getWindow().getDecorView().findViewById(android.R.id.content);
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.fade);
set.setTarget(v);
set.start();
#13 楼
对Kotlin使用以下功能:private fun animateColorValue(view: View) {
val colorAnimation =
ValueAnimator.ofObject(ArgbEvaluator(), Color.GRAY, Color.CYAN)
colorAnimation.duration = 500L
colorAnimation.addUpdateListener { animator -> view.setBackgroundColor(animator.animatedValue as Int) }
colorAnimation.start()
}
通过任何要更改颜色的视图。
#14 楼
我发现在Android源代码中ArgbEvaluator
使用的实现在过渡颜色方面表现最佳。使用HSV时,取决于两种颜色,过渡对我来说是通过太多的色调跳跃的。但是,这种方法就不行了。如果您像我一样,并且希望将过渡与输入中传递的某些用户手势或其他值相关联,则ArgbEvaluator
并没有太大帮助(除非您的目标对象是API 22及更高版本,在这种情况下,可以使用ValueAnimator
方法)。当定位到API 22以下时,将ValueAnimator
源代码中找到的代码包装到您自己的方法中,如下所示: >#15 楼
基于ademar111190的答案,我创建了此方法,该方法将在任意两种颜色之间脉动视图的背景颜色:private void animateBackground(View view, int colorFrom, int colorTo, int duration) {
ObjectAnimator objectAnimator = ObjectAnimator.ofObject(view, "backgroundColor", new ArgbEvaluator(), colorFrom, colorTo);
objectAnimator.setDuration(duration);
//objectAnimator.setRepeatCount(Animation.INFINITE);
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
// Call this method again, but with the two colors switched around.
animateBackground(view, colorTo, colorFrom, duration);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
objectAnimator.start();
}
#16 楼
您可以在API 11之上使用ArgbEvaluatorCompat类。implementation 'com.google.android.material:material:1.0.0'
ValueAnimator colorAnim = ValueAnimator.ofObject(new ArgbEvaluatorCompat(), startColor, endColor);
colorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mTargetColor = (int) animation.getAnimatedValue();
}
});
colorAnimation.start();
评论
人们会希望,对于Android之类的平台,颜色之间的平滑过渡不应该成为问题。不过,也许不是为此而建的。问题仍然存在。优秀的视频教程