Creating a
View
which slides back and forth between an original position and a displacement position is easy post- Ice Cream Sandwich (by means of the new
ObjectAnimator
class and
setTranslationX(float translationX)
etc methods). Doing this pre- Ice Cream Sandwich is not so easy. Below is a class I created which you can use as a basis for creating a
View
which toggles (slides) between an original position and a displacement position. The way it works is to extend
FrameLayout
(could be a different
View
depending on your need), to start the translate right/left animations when the
toggleSlide()
method is called, and to listen for the end of the animations in order to relocate itself 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, int defStyle)
{
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);
}
}
}
2 comments:
Hi Adil,
Sergio here.
To use the new com.andriod.animation API, available from Honeycomb in older API levels, you can use the library 9oldandroids:
http://nineoldandroids.com/
Hey Sergio,
Thanks for the comment :) As discussed offline, the 'nineoldandroids' library is handy for simplifying animation coding but has some limitations in that Views translated horizontally/vertically appear as moved but are still clickable in their original (pre-translate) locations.
Post a Comment