In
this part we will focus on solving advance animation problems in Android. We
have done simple animation in our previous tutorial now we will try create a
more complex animation in a simpler way. We
will create a simple animation that moves a Button from the top left corner of
the screen to the center when it is clicked, then remains there, and when
clicked again it moves back to its original position.
After you read the documentation http://developer.android.com/g uide/topics/resources/animatio n-resource.h... it may seem easy to solve. We can define the animation relative
to the parents size in percent (50%p), and the fillAfter attribute makes the
button remain there, instead of jumping back to its original position. We can
even define all of this in XML below.
1 <?xml version="1.0" encoding="utf-8"?>
2 <translate
xmlns:android="http://schemas.android.com/apk/res/android"
3
android:fromXDelta="0%p" android:fromYDelta="0%p"
4
android:toXDelta="50%p" android:toYDelta="50%p"
5
android:duration="1000"
6
android:fillAfter="true" />
But when you try this out, you will face two problems.
First, the button will not be properly centered, the buttons top left corner
will be in the center. Second, after it moved to the center it won’t be
clickable any more. The clickable area of the button does not move with the
animation, if you try to click at the original position of the button you will
be able to trigger the onclick again. Unfortunately such a simple code, like
the xml above will not be enough to fix these simple problem.
To properly center the button we must compute where the
buttons top left corner should be. When the button is clicked get the buttons
size, and its parent views size, compute where it should move, and create the
proper animation by code. Somehow we have to track where the button is, if it
is already in the middle, we have to reverse the animation. This can be done
like this:
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Button button = (Button) findViewById(R.id.button);
final RelativeLayout
mainContainer = (RelativeLayout)findViewById(R.id.mainContainer);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//have to get the sizes here instead of onCreate, in
onCreate size is not //computed
yet
int buttonHeight = button.getHeight();
int parentHeight = mainContainer.getHeight();
int buttonWidth = button.getWidth ();
int parentWidth = mainContainer.getWidth();
//detect if have to move to center, or already there and
have to move back
boolean isInCenter = button.getLeft()>0;
final int fromX = isInCenter?(parentWidth/2)-(buttonWidth/2):0;
final int fromY = isInCenter?(parentHeight/2)-(buttonHeight/2):0;
final int toX = isInCenter?0:(parentWidth/2)-(buttonWidth/2);
final int toY = isInCenter?0:(parentHeight/2)-(buttonHeight/2);
//create the animation
TranslateAnimation moveAnim = new TranslateAnimation(
TranslateAnimation.ABSOLUTE, fromX,
TranslateAnimation.ABSOLUTE, toX,
TranslateAnimation.ABSOLUTE, fromY,
TranslateAnimation.ABSOLUTE, toY);
moveAnim.setDuration(1000);
moveAnim.setFillAfter(true);
To solve the
clickinkig problem we have to really move the button when the animation ended.
This can be done by setting up an animation listener to detect the end of the
animation. In the listener we set up margins to do the move. Because of this we
have to remove this margins the next time we animate button or, the
margins will mess it up. So we also add a listener to detect the start of the
animation, and remove the margins there.
moveAnim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation
animation) {
//when the animation ended the button is really moved, to remain
clickable
LayoutParam params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.leftMargin = toX;
params.topMargin = toY;
button.setLayoutParams(params);
//remove the animation, its no longer needed, since button is
really there
button.clearAnimation();
}
@Override
public void onAnimationStart(Animation
animation) {
//remove the margins used to really move the button, or it messes
up the animation
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.leftMargin = 0;
params.topMargin = 0;
button.setLayoutParams(params);
}
@Override
public void onAnimationRepeat(Animation
animation) {
//do nothing
}
});
Enjoy....
Do post your doubts, queries or suggestions in this blog.
No comments:
Post a Comment