I have been working on adding animation to the card game I have been programming lately, and recently added in these xml files:
slide_up_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator" >
<translate
android:duration="#integer/config_slide_time"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
android:duration="#integer/config_slide_time"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<rotate
android:duration="#integer/config_slide_time"
android:fromDegrees="25"
android:pivotX="0"
android:pivotY="0"
android:toDegrees="0" />
</set>
slide_up_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator" >
<translate
android:duration="#integer/config_slide_time"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
android:duration="#integer/config_slide_time"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<rotate
android:duration="#integer/config_slide_time"
android:fromDegrees="-25"
android:pivotX="100%"
android:pivotY="0"
android:toDegrees="0" />
</set>
integers.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="config_slide_time">800</integer>
</resources>
Shortly after, I came to the realize that my cards are drawables, so the only way I can get motion is by moving the entire canvas, and that's going to create too many problems. Is there any way I can move the cards individually without the canvas, or am I going to have to reset all the cards as images instead of drawables?
Since the android.view.animation package is meant for animating Views, you will have to manage the animations yourself, although you can still use your animations that you have defined in XML.
I'm assuming you are doing the drawing in some custom View.
First, define a Transformation variable and an Animation variable in your View class:
private Animation mAnimation;
private Transformation mTransformation = new Transformation();
When you want to start the Animation, inflate one:
mAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up_left);
Then, set the start time and initialize the size:
mAnimation.setStartTime(getDrawingTime());
Rect drawableBounds = mDrawable.getBounds();
mAnimation.initialize(drawableBounds.width(), drawableBounds.height(), getWidth(), getHeight());
Now, in onDraw(), pass in the current time and the transformation to update the transformation, and then apply it to the canvas before drawing:
public void draw(Canvas canvas) {
mAnimation.getTransformation(getDrawingTime(), mTransformation);
s.save();
s.concat(mTransformation.getMatrix());
mDrawable.setAlpha((int) (mTransformation.getAlpha() * 0xFF));
mDrawable.draw(canvas);
s.restore();
}
That's a basic approach to doing it yourself. You'll have to manage the state of the animation, clean it up when the animation is over, create and position the Drawable(s), and handle nulls and other View state, but this should give you a starting point.
I would also highly recommend looking into ObjectAnimator, which is the new and better way to do animations.
Related
Is it possible to write slide_out_left animation using java?
Here is my animation xml.
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:duration="300" android:fromXDelta="0%" android:toXDelta="-100%" />
</set>
yes it is possible:
view.animate().translationX(_amount_).setDuration(_time in ms_).start();
So, you will have to calculate translation distance by yourself.
Note: if you translate to 0 later, after some other translations - it will move to starting position.
To complete slide in effect try to use withStartAction also.
I've got a BubbleTextView which is basically a TextView with some additions used in Launcher3 to display icons on the homescreen. I'm trying to animate this view via this XML
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/anticipate_interpolator"
android:duration="#android:integer/config_shortAnimTime"
android:startOffset="350"
android:fillAfter="true" >
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<translate
android:fromYDelta="0"
android:toYDelta="200" />
</set>
But whenever I start the animation it'll only translate the image and the alpha part won't work, so there is no fade out animation. What am I doing wrong here?
I figured out that BubbleTextView overrides onSetAlpha
#Override
protected boolean onSetAlpha(int alpha) {
if (mPrevAlpha != alpha) {
mPrevAlpha = alpha;
super.onSetAlpha(alpha);
}
return true;
}
Seems to be some relict of older revisions.
Since the implementation is not needed anymore it's safe to either delete the method or return false instead.
I am trying to start an animation AFTER 1 second. I have used the attribute "android:startOffset" in my XML file, but it does not work completely the way I expected. I was expecting the view to NOT EVEN BE DRAW in its initial position (that is, the position set in the attributes "fromXDelta" and "fromYDelta") before the offset I set has passed. Here is my XML:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially"
android:shareInterpolator="false" >
<translate
android:duration="2000"
android:startOffset="1000"
android:fromXDelta="-70%p"
android:fromYDelta="0%p"
android:interpolator="#android:anim/linear_interpolator"
android:toXDelta="+0%p"
android:toYDelta="0%p" />
</set>
If I try to move my view using the above animation, the view is drawn IMMEDIATELY at the position -70% of the screen. Then the one second passes and then, as expected, the animation kicks in and starts to move the view. However, I DO NOT want the view to be drawn at all before that 1 second!. How can I achieve this?
Thank you in advance.
UPDATE
I am calling the above XML just after a startActivity call (the *R.anim.animation_coming_in* below), like this:
startActivity(new Intent(this, ThankYouActivity.class));
overridePendingTransition(R.anim.animation_coming_in, R.anim.animation_coming_out);
You could try using a pair of alpha animations with very short duration so that the view is hidden until it's needed. Something like this:
<set ...>
<alpha
android:fromAlpha="0.0"
android:toAlpha="0.0"
android:duration="1"
android:startOffset="0" />
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="1"
android:startOffset="1000" />
<translate
...
/>
</set>
Alternatively, you could implement this set of animations in code. Doing so would enable you to use a Handler to start the animation after a delay so that the view is hidden until the animation starts.
I'm trying to customize the animation between two activities by fading out the splashscreen and fading in the main activity.
I trying two solutions, one with fade_in.xml and fade_out.xml where controlling alphas (0-1 , 1-0) and calling everything with overridePendingTransaction(fade_in, fade_out) and one with fade and hold like ni api demo (api/app/animation/fade);
The main problem is that the splashscreen (first animation ) is losing its alpha while sliding to the right as well and the second activity is appearing as wanted.
How is possible to lock the splashscreen to its original position and just making it fading out?
fade
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="#android:integer/config_longAnimTime" />
hold
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator"
android:fromXDelta="0" android:toXDelta="0"
android:duration="#android:integer/config_longAnimTime" />
overridePendingTransition(R.anim.fade, R.anim.hold);
You can use the callback for .fadeOut().
I've a simple view animation, but I can't see to get "rid" of the animation "unwinding" (and I can't seem to find a solution online).
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:shareInterpolator="true" >
<scale
android:duration="250"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:toXScale="1.1"
android:toYScale="1.1" />
</set>
What this does is, simply, inflates the View by 10% proportionally, from the middle.
But, when it executes, it inflates and, when it reaches the end, it deflates back. I want to avoid that -- the "unwinding" effect -- when it scales back from 110% to 100%.
How can that be done?
Edit:
I'm starting it simply with this:
Animation animation1 = AnimationUtils.loadAnimation(this, R.anim.<name>);
v.startAnimation(animation1);
The correct answer is found here: How can I animate a view in Android and have it stay in the new position/size?
It is putting this:
android:fillAfter="true"
android:fillEnabled="true"
inside the <set tag.