At the first click of a button, I want to slide a View
along the x-axis (by 200 pixels to the right let\'s say). And on the second press of the button, I want t
This one's had me stumped for a fair few days (getting it to work pre- Ice Cream Sandwich) but I think I've finally got there! (thanks to Gautam K and Mike Israel for the leads) What I did in the end was to extend my View
(a FrameLayout
) to start the translate right/left animations as required and to listen for the end of the animations in order to relocate my FrameLayout
right/left as appropriate, as follows:
public class SlidingFrameLayout extends FrameLayout
{
private final int durationMilliseconds = 1000;
private final int displacementPixels = 200;
private boolean isInOriginalPosition = true;
private boolean isSliding = false;
public SlidingFrameLayout(Context context)
{
super(context);
}
public SlidingFrameLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public SlidingFrameLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
@Override
protected void onAnimationEnd()
{
super.onAnimationEnd();
if (isInOriginalPosition)
offsetLeftAndRight(displacementPixels);
else
offsetLeftAndRight(-displacementPixels);
isSliding = false;
isInOriginalPosition = !isInOriginalPosition;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
{
super.onLayout(changed, left, top, right, bottom);
// need this since otherwise this View jumps back to its original position
// ignoring its displacement
// when (re-)doing layout, e.g. when a fragment transaction is committed
if (changed && !isInOriginalPosition)
offsetLeftAndRight(displacementPixels);
}
public void toggleSlide()
{
// check whether frame layout is already sliding
if (isSliding)
return; // ignore request to slide
if (isInOriginalPosition)
startAnimation(new SlideRightAnimation());
else
startAnimation(new SlideLeftAnimation());
isSliding = true;
}
private class SlideRightAnimation extends TranslateAnimation
{
public SlideRightAnimation()
{
super(
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, displacementPixels,
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0);
setDuration(durationMilliseconds);
setFillAfter(false);
}
}
private class SlideLeftAnimation extends TranslateAnimation
{
public SlideLeftAnimation()
{
super(
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, -displacementPixels,
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0);
setDuration(durationMilliseconds);
setFillAfter(false);
}
}
}
And, lastly, to slide the SlidingFrameLayout
right/left, all you've got to do is call the SlidingFrameLayout.toggleSlide()
method. Of course you can tweak this SlidingFrameLayout
for your purposes to slide a greater number of pixels, to slide for longer etc, but this should be sufficient to get you started :)
I had a similar issue, TranslateAnimation does actually move the view if you call setFillAfter now (android bug). I had to do something similar so I said, hey lets use an animation listener and then just move everything to the correct location. Unfortunately there is a bug on animation listeners as well (stackoverflow solution). So I created my own layout class according to the solution in the stackoverflow solution and I was good to go :)
Try looking into ObjectAnimator and its super class Value Animator
you can do something like this
ObjectAnimator anim = ObjectAnimator.ofFloat(this, "translationX", 0,200);
and then
anim.start();
Use a boolean
value and toggle it with 200,0
in the object animator to slide back
PS: you can use setDuration
method to set how long the animation should take to complete
Try looking at the support library which provides backward compatibility.
As @AdilHussain pointed out there is a library called nineoldandroids which can be used for the same purpose on older androids.