Как оживить просмотр перевода

При первом нажатии кнопки я хочу сдвинуть View вдоль оси x (на 200 пикселей вправо, допустим). И при втором нажатии кнопки я хочу сдвинуть View назад по оси X в исходное положение.

Метод View.setTranslationX(float) перескакивает представление в целевые горизонтальные местоположения с вызовами myView.setTranslationX(200); и myView.setTranslationX(0); соответственно. Кто-нибудь знает, как я могу поместить View в целевые горизонтальные местоположения вместо?

Примечание 1: A TranslateAnimation не является хорошим, поскольку он фактически не перемещается View, но только представляет иллюзию его перемещения.

Примечание 2: Я не понимал во время постановки вопроса о том, что методы setTranslationX(float) и setTranslationY(float) были введены как API уровня 11. Если вы нацеливаете Honeycomb ( API Level 11) вверх, то ответа Gautam K будет достаточно. В противном случае см. Мой ответ для предлагаемого решения.

Ответ 1

Этот меня заставил меня смутиться в течение нескольких дней (заставить его работать до мороженого сэндвич), но я думаю, что я, наконец, добрался туда! (спасибо Гаутаму К и Майку Израилю за потенциальных клиентов). В конце концов, я сделал расширение View (a 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 для своих целей, чтобы скользить большее количество пикселей, скользить дольше и т.д., Но этого должно быть достаточно, чтобы вы начали:)

Ответ 2

Попробуйте найти ObjectAnimator и его суперкласс Value Animator

вы можете сделать что-то вроде этого ObjectAnimator anim = ObjectAnimator.ofFloat(this, "translationX", 0,200); а потом anim.start();

Используйте значение boolean и переключите его с помощью 200,0 в аниматоре объектов, чтобы отступить назад

PS: вы можете использовать метод setDuration, чтобы установить, сколько времени потребуется анимации для завершения

Изменить:

Попробуйте найти библиотеку поддержки которая обеспечивает обратную совместимость.

Изменить

Как заметил @AdilHussain, есть библиотека под названием nineoldandroids, которая может использоваться для той же цели для старых андроидов.

Ответ 3

У меня была аналогичная проблема, TranslateAnimation действительно переводит представление, если вы вызываете setFillAfter сейчас (ошибка Android). Я должен был сделать что-то подобное, поэтому я сказал, что он позволяет использовать прослушиватель анимации, а затем просто переместить все в нужное место. К сожалению, есть и ошибка для прослушивателей анимации (fooobar.com/info/25353/...). Поэтому я создал свой собственный класс макета в соответствии с решением в fooobar.com/info/25353/..., и мне было хорошо идти:)