Как оживить перевод 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 за лидерство) В итоге я продлил ViewFrameLayout), чтобы начать перевод правой / левой анимации, как требуется, и прослушать конец анимации, чтобы переместить мой 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, и я был готов пойти:)

Другие вопросы по тегам