Custom animation in Android
I assume you create each frame as a bitmap, and then pass it to the Animation directly, instead of getting the Drawable from resource.
Bitmap bm = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_888);
Canvas c = new Canvas(bm);
.... Draw to bitmap
animation.addFrame(bm,50)
.... repeat for all frames you wish to add.
Most flexible (and pretty easy) way to create custom animation is to extend Animation
class.
In general:
- Set duration of your animation using
setDuration()
method. - Optionally set the interpolator for your animation using
setInterpolator()
(for exapmle you can useLinearInterpolator
orAccelerateInterpolator
etc.) - Override
applyTransformation
method. Here we interested ininterpolatedTime
variable which changes between 0.0 and 1.0 and represent the your animation progress.
Here is an example (I'm using this class to change ofsset of my Bitmap
. Bitmap
itself is drawn in draw
method):
public class SlideAnimation extends Animation {
private static final float SPEED = 0.5f;
private float mStart;
private float mEnd;
public SlideAnimation(float fromX, float toX) {
mStart = fromX;
mEnd = toX;
setInterpolator(new LinearInterpolator());
float duration = Math.abs(mEnd - mStart) / SPEED;
setDuration((long) duration);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
float offset = (mEnd - mStart) * interpolatedTime + mStart;
mOffset = (int) offset;
postInvalidate();
}
}
Also you can modify View
by using Transformation#getMatrix()
.
UPDATE
In case if you're using Android Animator framework (or compatibility implementation - NineOldAndroids
) you can just declare setter and getter for your custom View
property and animate it directly. Here is an another example:
public class MyView extends View {
private int propertyName = 50;
/* your code */
public int getPropertyName() {
return propertyName;
}
public void setPropertyName(int propertyName) {
this.propertyName = propertyName;
}
/*
There is no need to declare method for your animation, you
can, of course, freely do it outside of this class. I'm including code
here just for simplicity of answer.
*/
public void animateProperty() {
ObjectAnimator.ofInt(this, "propertyName", 123).start();
}
}
Animation animation = new AnimationDrawable();
animation.addFrame(getResources().getDrawable(R.drawable.exp1), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp2), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp3), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp4), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp5), 50);
animation.addFrame(getResources().getDrawable(R.drawable.exp6), 50);
This is the code that I use to produce a custom, frame-by-frame animation in my onCreate().
After that I need to start the animation, but must do so inside the UI thread. Therefore I make use of Runnable.
class Starter implements Runnable {
public void run() {
animation.stop();
animation.start();
}
}
I start that Runnable from an onClick() using the .post() method of ImageView:
((ImageView) findViewById(R.id.ImageToAnimateOnClicking)).post(new Starter());
My custom animation when replacing Fragment with another Fragment:
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
.replace(currentFragment.getId(), newFragment).commit();
currentFragment = newFragment;
XML slide_in_right:
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="1000"/>
XML slide_out_left:
<translate android:fromXDelta="0" android:toXDelta="-100%p"
android:duration="1000"/>