I'd like to create an indeterminate animation that simply fades from one color to another (a pulse, if you will). I don't think this should require the use of images but despite my best efforts, I'm not sure I understand how to use something like AlphaAnimation with a Shape to accomplish this.
Could someone please provide some insight as to how to accomplish this? I have a feeling I'm missing something pretty straightforward here. (Examples are always appreciated!)
Thanks!
This is a trivial task in 3.0 - you can set up an ObjectAnimator to change the "color" or "backgroundColor" of an object (View, ColorDrawable, whatever has the property) between two values. See the ApiDemo animations/BouncingBalls for an example of this.
But assuming you're using pre-3.0 APIs, there are a couple of approaches. First, you could set up your own handler to give you the timing events you need, then calculate the new color at each point.
It's probably slightly easier (if not entirely intuitive) to use an AlphaAnimation. All you really want from the animation is percentage values, not to fade anything. So you don't set the animation on a view, but just set it up to run internally from a value of 0 to 1, then get the current animated value in your onDraw() method and set the current color appropriately.
For example, this will set up and start the alpha animation to run for one second:
Transformation transform = new Transformation();
AlphaAnimation anim = new AlphaAnimation(0f, 1f);
anim.setDuration(1000);
anim.start();
Then in your drawing loop, you grab the current animated value:
long time = getDrawingTime();
anim.getTransformation(time, transform);
float elapsedFraction = transform.getAlpha();
Once you have the elapsedFraction (a value between 0 and 1), you can calculate the appropriate in-between color value.
The code above may not match your situation exactly, but you should be able to do something similar to get what you want.
Related
I want to rotate a simple imageview which has an elevation of 5dp.
animRotate=ObjectAnimator.ofFloat(imgProgress, "rotationY", 0, 360);
animRotate.setDuration(ANIM_DURATION);
animRotate.setRepeatCount(5);
animRotate.start();
The animation for the above code is smooth if the android:elevation value for the ImageView is not set in the layout file. But when i set the elevation, the animation becomes jerky.
Can someone please suggest a fix?
Maybe the reason is that you create and run animatuion at once. As docs say, it is better first to init your animation
//OnCreate
animRotate=ObjectAnimator.ofFloat(imgProgress, "rotationY", 0, 360);
animRotate.setDuration(ANIM_DURATION);
animRotate.setRepeatCount(5);
And then when it is time for animation to be fired run it
animRotate.start();
Also, consider reading about what PivotX and PivotY are, it may be useful.
Also, using default interpolator will give strange result for rotating 5 times - i think using simple linear interpolator is much better choice.
I am trying to animate alpha of an Android view (two animations, both fade in and fade out). It all works fine if the view's alpha is initially 1, by default. However, I want that view to be transparent initially, hence I've set it's alpha to zero:
indicatorContainer.setAlpha(0);
Now, the animations won't work. It will never become visible. If I comment out that line, the view is initially displayed (which I don't want), but my animations works fine when I invoke them. I though it's something trivial but apparently it's not. What am I doing wrong?
UPDATE: I've also tried a floating point 0f instead of integer 0 after reading some API changes involving the setAlpha method, thinking that my call may be calling the incorrect overload, but nothing changed.
Try something like this:
mRelativeLayout.setAlpha(0f);
mRelativeLayout.animate().alpha(1f).setDuration(500).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mRelativeLayout.setVisibility(View.VISIBLE);
//OR
mRelativeLayout.setAlpha(1f);
}
});
I faced same issue where indicatorContainer is ImageButton.
Below code fixes this very, very annoying issue...
// XXX: Does not work if just 0. It calls `ImageView#setAlpha(int)` deprecated method.
indicatorContainer.setAlpha(0.0f);
ViewCompat.animate(indicatorContainer).alpha(1);
One can try following, a more simple way:
view.animate().alpha(1).setDuration(ANIMATION_DURATION);
This might be irrelevant to the OP but I thought I'd share it regardless as it might help someone out in the future.
Please be aware that if you're initial animation combines animate().alpha(0.0f) with a manipulation of the View's Y or X-axis translation (e.g. animate().translationYBy(500) you have to reset this property before fading back in (using animate().alpha(1.0f).
I came across this SO post thinking that setting alpha back to 1.0f was failing when in actual fact it was still working as it should, but the animation was occurring off screen because I hadn't reset my Y-Axis translation (Homer Simpson *doh* moment).
Handily, to easily resolve this issue, you can add a AnimatorEndListener to your animation for when it finishes (as #Nikhil Verma mentioned above) where you can add a single line of code to reset the X/Y-axis translation.
In the scenario I faced I wanted the animation to float down and fade out so adjusted the Y-axis & alpha accordingly. After it had floated and faded I set a Listener to reset the Y axis translation like so:
loadingMask.animate().translationYBy(500); //starts animation by moving it down the screen
loadingMask.animate().alpha(0.0f) //fades out
.setDuration(1500) //over 1.5s
.setListener(new AnimatorEndListener() { //when animation completes
#Override
public void onAnimationEnd(Animator animation) {
loadingMask.setTranslationY(0); //reset the y axis translation
}
});
Now, when I want the animation to repeat again, I can set the alpha of my View to 1.0f and it works as intended.
Here's how I was able to kinda solve for this - not particularly elegant, but manageable:
Set the view to the initial alpha you want 0.0f or otherwise.
When the event occurs where you need the view to have more (or less) visibility/alpha - eg, right before you start an animation - at that point you can update the alpha and then run the animation on the view
I'm still getting some choppiness when the animation repeats, but this approach might work for scenarios where the animation is not repeated
I have an image, which I have already clipped in circle. I want this image to animate over an oval path within angle 20 to 135.
I have searched a lott but i dint get exact answer.
Any help will be greatly appreciated?
This animation can be achieved using the Android Accelerometer and the Sensor Manager class.
Refer to this link. It has 3 different detailed sample codes.
Moving an image using Accelerometer of android
Hope it helps.
Check this out, I was able to move an image on a path.
You can simply define path
AnimatorPath path = new AnimatorPath();
path.moveTo(0, 0);
path.lineTo(0, 300);
path.curveTo(100, 0, 300, 900, 400, 500);
public static ObjectAnimator ofObject (Object target, String propertyName, TypeEvaluator evaluator, Object... values)
Constructs and returns an ObjectAnimator that animates between Object values. A single value implies that that value is the one being animated to. Two values imply a starting and ending values. More than two values imply a starting value, values to animate through along the way, and an ending value (these values will be distributed evenly across the duration of the animation).
Parameters
target: The object whose property is to be animated. This object should have a public method on it called setName(), where name is the value of the propertyName parameter.
propertyName: The name of the property being animated.
evaluator: A TypeEvaluator that will be called on each animation frame to provide the necessary interpolation between the Object values to derive the animated value.
values: A set of values that the animation will animate between over time.
Returns
An ObjectAnimator object that is set up to animate between the given values.
For more reference you may check here.
As we know , the android coordinate system is start from the top left corner of the android screen. The x-axis is down growth and the y-axis is right growth.But I found it's not right for the animation.
For example, I initialized the TranslateAnimation using the constructed function:
TranslateAnimation ta = new TranslateAnimation(0.0f, 200, 0.0f, 200);
Does the coordinate system have changed ? I found it didn't start from the top left corner.
Then I initialized the other translateAnimation for moving up and right direction :
TranslateAnimation ta = new TranslateAnimation(0.0f, 200, 0.0f, -200);
ta.setReaptMode(Animation.REVERSE);
The same behavior would be found.
I am confused about it.
I believe that constructor for TranslateAnimation uses deltas. See this. Or look at the constructor sig. : (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta). So if you want your anim. to jump up first, you could use a negative third ctor param.
More precisely:
An animation can never start until after the layout has been measured. One usually shouldn't have to worry about how this works beyond that the algorithm is mostly very good and you can take control of its strategies by setting layout parameters. In short, by the time an animation might be started, we know where you want the view to be on the screen, because you set layout parameters.
Translate animation then takes deltas from that position. So your current animation shouldn't start from the top left, but rather wherever those layout params were evaluated by onMeasure.
Some would say- how annoying. It's gonna get complicated even if you just want to do some simple up-down type animations... Well, here's an advisable development strategy; it snould make android animation development a breeeze. Set an animationListener on every animation. In onAnimationEnd, in possibly a parametized way, reset the layout parameters on the view your animating to where you expect it to be. That way, you'll get no surprising "jumps" when you re-apply an animation again. You may need to invalidate in some circumstances, or clearAnimation. The reason that this works is that the measure pass will be caused to come round again and you'll have a new offset for your TranslateAnimation. Finally, you may want to do all this resetting posted to the message queue of a view using post(Runnable runnable) in the listener, so you're off the last pass of the animation draw.
I too found android Animations can occasionally surprise you and cause jumpy behaviour. But if you do it like this, constructors taking delta params shouldn't be confusing again.
I am starting to play around with Property Animations over view animations as I have a view that needs to scale and push others out of the way as it does. I've seen some examples but I'm just wondering if there is anywhere that provides a list of the properties that can be altered using these classes. For example, I saw one tutorial that did a quick rotation using:
ObjectAnimator.ofFloat(aniView, "rotation", 360)
Which is quite cool, but I wouldn't have known the rotation property if not for that exact tutorial, is there any comprehensive list of what can be done? The particular property I want to animate is the weight of a view within a LinearLayout, if anyone has any advice on that specifically.
Better late than never, so here is the comprehensive list of the properties that can be animated with ObjectAnimator.
http://developer.android.com/guide/topics/graphics/prop-animation.html#views
The Docs imply that any value can be used with ObjectAnimator as long as you follow a naming convention:
The object property that you are animating must have a setter function (in camel case) in the form of set<propertyName>(). Because
the ObjectAnimator automatically updates the property during
animation, it must be able to access the property with this setter
method. For example, if the property name is foo, you need to have a
setFoo() method. If this setter method does not exist, you have three
options:
Add the setter method to the class if you have the rights to
do so.
Use a wrapper class that you have rights to change and have
that wrapper receive the value with a valid setter method and forward
it to the original object.
Use ValueAnimator instead.
[...]
With respect to your question, View has the method setRotation(float) -- that gives you a hint it can be used. In particular here's how you would do it with a particular TimeInterpolator:
ObjectAnimator anim = ObjectAnimator.ofFloat(myView, "rotation", 0f, 90f);
anim.setDuration(2000); // Duration in milliseconds
anim.setInterpolator(timeInterpolator); // E.g. Linear, Accelerate, Decelerate
anim.start() // Begin the animation
You can read the docs for more details on the expectations of ObjectAnimator.
Here is the comprehensive list of property names that you are looking for:
rotation
rotationX
rotationY
translationX
translationY
scaleX
scaleY
pivotX
pivotY
alpha
x
y
Source: Docs
Use "translateX" or "transalteY" to move a <group>
Take a look at vectorDrawable
You can check it at the View.java file in Properties block. Now it starts with the line of:
public static final Property<View, Float> ALPHA = new FloatProperty<View>("alpha")