I am a beginner in Android development.
Coming from iOS background I tend to use animations on Views
to animate a View in Android. I have found out to do it in a "normal" way
For example to animate alpha value of a view
valueAnimator = ValueAnimator.ofFloat(0, 100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) animation.getAnimatedValue();
viewToAnimate.alpha(value);
}
});
valueAnimator.setDuration(10000);
valueAnimator.start();
I am wondering if there is an easy way. Perhaps create a "Helper" class to animate an objects alpha value. Where we can pass in the View to animate and have it animated.
Something like AnimationHelper.animateAlpha(viewToAnimate, OF_VALUE, TO_VALUE, DURATION);
I am sorry to ask this question. Since my Java knowledge is rusty, I am wondering if there is any kind folks out there who is willing to help out.
Thank you
Try this:
viewToAnimate.animate().alpha(TO_VALUE).setDuration(DURATION);
or this:
ObjectAnimator anim = ObjectAnimator.ofFloat(viewToAnimate, "alpha", FROM_VALUE, TO_VALUE);
anim.setDuration(DURATION);
anim.start();
Related
Here i am trying to move a view on a path with ObjectAnimator and also need to set one more scale animation on same view.
ObjectAnimator objectAnimator = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP)
{
objectAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
}
if (objectAnimator != null) {
objectAnimator.setDuration(2500);
objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator.start();
view.startAnimation(scaleRection);// this is not working because changing of x y position
need to start another Animation when objectAnimator.start();
also tried with listener
objectAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
view.startAnimation(scaleRection);
}
#Override
public void onAnimationEnd(Animator animation)
{
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
You can also use an AnimatorSet play together https://developer.android.com/reference/android/animation/AnimatorSet.html#playTogether and it's builder function https://developer.android.com/reference/android/animation/AnimatorSet.Builder
To play Two ObjectAnimator together
e.g.
AnimatorSet animationSet = new AnimatorSet();
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view,"scaleY", 1f, 0f);
scaleY.setDuration(5000);
scaleY.setInterpolator(new AccelerateDecelerateInterpolator());
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view,"scaleX", 1f, 0f);
scaleX.setDuration(5000);
scaleX.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.playTogether(scaleX, scaleY);
animationSet.start();
I would suggest using ViewPropertyAnimator.
From the docs :
This class enables automatic and optimized animation of select
properties on View objects. If only one or two properties on a View
object are being animated, then using an ObjectAnimator is fine; the
property setters called by ObjectAnimator are well equipped to do the
right thing to set the property and invalidate the view appropriately.
But if several properties are animated simultaneously, or if you just
want a more convenient syntax to animate a specific property, then
ViewPropertyAnimator might be more well-suited to the task.
This class may provide better performance for several simultaneous
animations, because it will optimize invalidate calls to take place
only once for several properties instead of each animated property
independently causing its own invalidation. Also, the syntax of using
this class could be easier to use because the caller need only tell
the View object which property to animate, and the value to animate
either to or by, and this class handles the details of configuring the
underlying Animator class and starting it.
You can chain as many animations as you like at once in one line of code :
view.animate().translationX(...).translationY(...).scaleX(...).scaleY(...).setInterpolator(new AccelerateDecelerateInterpolator()).setDuration(2500);
if you need different values for your duration or similar, you can do it with two lines :
view.animate().translationX().setDuration(...) ...
view.animate().scaleX().setDuration(...) ...
There are also methods translationXBy() and scaleXBy() which might be more suitable for your case, and you can also set a listener etc. Check the docs for all available methods
I've made a custom view for visualizes the progress. It has a simple intro animation like the below :
PropertyValuesHolder c=PropertyValuesHolder.ofInt("c",0,100);
ValueAnimator anim=new ValueAnimator();
anim.setValues(c);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
position = (int) animation.getAnimatedValue("c");
postInvalidate();
}
});
anim.setDuration(1000);
anim.start();
It works smoothly with about 50 keyframes, but after the AdView that placed on the parent view, turns visible the same animation runs with lags (performance reduced to about 20 keyframes). I check the ValueAnimator.FrameDelay, it doesn't change.
What causes this problem, And what is the solution?
As #MartinMarconcini said, the problem related to the WebView that embedded inside the AdView. The performance improved by enabling Hardware Acceleration on the AdView.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
adView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
else adView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
I'm trying to create smooth color animation in my WaveView. Unfortunatelly animation is creating rainbow effect spamming through every color from start to end.
I'll need it to go from Red to Green with just (Red -> Orange - > Yellow - > Greenish -> Green) like on RGB tables.
Here's my ObjectAnimator:
ObjectAnimator waveColor = ObjectAnimator.ofInt(
mWaveView, "waveColor",Color.parseColor("#64ff0000"),Color.parseColor("#6400ff00"));
waveColor.setDuration(7000);
waveColor.setInterpolator(new LinearInterpolator());
animators.add(waveColor);
I have no idea how to make it to just go through that colors.
Check this Link:
Hope I have understood your question properly and it helps
ColorDrawable[] color = {new ColorDrawable(Color.RED), new ColorDrawable(Color.GREEN)};
TransitionDrawable trans = new TransitionDrawable(color);
//This will work also on old devices. The latest API says you have to use setBackground instead.
mWaveView.setBackgroundDrawable(trans);
trans.startTransition(7000);
best way use ValueAnimator and 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.setColorBackground(ColorUtils.blendARGB(Color.parseColor("#FFFFFF")
, Color.parseColor("#000000")
, fractionAnim));
}
});
valueAnimator.start();
Since API16 ImageView.setImageAlpha(int) should be used instead of View.setAlpha(float) for better performance.
But how can I animate that value? I tried ValueAnimator without success.
ObjectAnimator.ofInt(imageView, "imageAlpha", 0).start();
I mean what Chet Haase is talking about here http://youtu.be/vQZFaec9NpA?t=33m
It should be fine. Maybe you forgot to specify the animation duration, or your alpha values are wrong (negative, too small, too close to notice)?
You can always animate using custom listener. It's longer, but easier to debug:
ValueAnimator animator = ValueAnimator.ofInt(0,255);
animator.setDuration(300);
animator.setInterpolator(new DecelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
imageView.setImageAlpha(valueAnimator.getAnimatedValue());
}
});
animator.start();
So I'm using a ValueAnimator to animate a stick figure's limbs from one position to another, in an infinite loop, or at least until the animation is stopped. My problem is that when the animator repeats I have a slight pause as if the animation is lagging behind, but it only happens when the animation repeats. I have other animations that only happen once and those run perfectly smoothly, and they have just as much computation each time so I'm currently thinking that it's a problem with the ValueAnimator.
In the past I was able to find other people complaining about this problem, but I haven't been able to find anyone who has found a solution. Do you guys know if this is a real problem with the Android ValueAnimator? If so, do you know of any solutions? If not, do you guys have any ideas as to why this could be happening to me in just that one place in the animation? I'm really stuck on this one.
My code for the ValueAnimator setup is this:
mFigureAnimator = ValueAnimator.ofFloat(0f, 1f);
mFigureAnimator.setInterpolator(new LinearInterpolator());
mFigureAnimator.setDuration(1000);
mFigureAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Float delta = (Float)animation.getAnimatedValue();
// Set the drawn locations based on the animated time and the start/end
invalidate();
}
});
mFigureAnimator.setRepeatCount(ValueAnimator.INFINITE);
mFigureAnimator.setRepeatMode(ValueAnimator.RESTART);
mFigureAnimator.start();
for Animation, you can configure the interpolator as LinearInterpolator in the animation file :
android:interpolator="#android:anim/linear_interpolator"
for Animator, LinearInterpolator also work for me, I had a rotate animator, do 360 degrees rotation and repeat infinite:
public class RotateAnimator {
private float mDegrees;
private ObjectAnimator mAnim;
private RotateAnimator() {
mAnim = ObjectAnimator.ofFloat(this, "degrees", 360);
mAnim.setInterpolator(new LinearInterpolator());
mAnim.setRepeatCount(ValueAnimator.INFINITE);
mAnim.setRepeatMode(ValueAnimator.INFINITE);
mAnim.setEvaluator(new FloatEvaluator());
mAnim.setDuration(2000);
mAnim.start();
}
public float getDegrees() {
return mDegrees;
}
public void setDegrees(float degrees) {
this.mDegrees = degrees;
// invalidate the view so it can redraw itself
invalidate();
}
}
that way solved my problem, if you couldn't find another solution, hope this can help you, good luck.