Как оживить перевод View
При первом нажатии кнопки я хочу View
вдоль оси х (скажем, на 200 пикселей вправо). И при втором нажатии кнопки, я хочу сдвинуть View
назад вдоль оси х в исходное положение.
View.setTranslationX(float)
метод перебрасывает вид на целевые горизонтальные локации с вызовами myView.setTranslationX(200);
а также myView.setTranslationX(0);
соответственно. Кто-нибудь знает, как я могу сдвинуть View
вместо целевых горизонтальных локаций?
Примечание 1: А
TranslateAnimation
не годится, так как на самом деле это не двигаетView
но только создает иллюзию его движения.Примечание 2: я не осознавал во время постановки вопроса, что
setTranslationX(float)
а такжеsetTranslationY(float)
методы были введены начиная с уровня API 11. Если вы нацелены на соту (уровень API 11) и выше, то ответа Гаутамы К. будет достаточно. В противном случае, смотрите мой ответ для предлагаемого решения.
3 ответа
Это заставило меня остаться в тупике на несколько дней (заставить его работать до сэндвича с мороженым), но я думаю, что наконец-то добрался! (спасибо Gautam K и Mike Israel за лидерство) В итоге я продлил View
(а FrameLayout
), чтобы начать перевод правой / левой анимации, как требуется, и прослушать конец анимации, чтобы переместить мой FrameLayout
вправо / влево, в зависимости от ситуации, следующим образом:
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);
}
}
}
И, наконец, чтобы скользить SlidingFrameLayout
вправо / влево, все, что вам нужно сделать, это позвонить SlidingFrameLayout.toggleSlide()
метод. Конечно, вы можете настроить это SlidingFrameLayout
для ваших целей, чтобы скользить большее количество пикселей, чтобы скользить дольше и т. д., но этого должно быть достаточно, чтобы начать:)
Попробуйте заглянуть в ObjectAnimator и его суперкласс Value Value Animator
вы можете сделать что-то вроде этого ObjectAnimator anim = ObjectAnimator.ofFloat(this, "translationX", 0,200);
а потом anim.start();
Использовать boolean
значение и переключать его с 200,0
в объекте аниматора скользить назад
PS: вы можете использовать setDuration
метод, чтобы установить, сколько времени анимация должна занять, чтобы завершить
Редактировать:
Попробуйте посмотреть в библиотеке поддержки, которая обеспечивает обратную совместимость.
редактировать
Как отметил @AdilHussain, есть библиотека под названием http://nineoldandroids.com/, которую можно использовать для тех же целей на старых андроидах.
У меня была похожая проблема, TranslateAnimation действительно перемещает представление, если вы вызываете setFillAfter сейчас ( ошибка Android). Мне пришлось сделать что-то похожее, поэтому я сказал: "Эй, давайте использовать слушателя анимации, а затем просто переместить все в правильное место". К сожалению, есть ошибка и для слушателей анимации ( решение stackru). Таким образом, я создал свой собственный класс макета в соответствии с решением в решении stackru, и я был готов пойти:)