Android: Обновление позиции линейного описания после завершения анимации

#android #animation

#Android #Анимация

Вопрос:

Мы были бы весьма признательны за любую помощь в решении следующей проблемы. Я знаю, что мне нужно сделать, и я проверил документы разработчика, но точный синтаксис, который мне нужно использовать, ускользает от меня (я новичок).

Вот что я делаю. У меня есть translate.xml файл в res / anim, который работает нормально. Это выглядит следующим образом:

 <translate xmlns:android="http://schemas.android.com/apk/res/android" 
   android:fromXDelta="0%" 
   android:toXDelta="0%" 
   android:fromYDelta="0%" 
   android:toYDelta="10%" 
   android:repeatCount="0" 
   android:duration="1000" 
   android:fillEnabled="true" 
   android:fillAfter="true"/>
  

Я выполняю свой код следующим образом:

     l = (LinearLayout) findViewById(R.id.linearLayout1);
    a = AnimationUtils.loadAnimation(this, R.anim.translate);
    a.setAnimationListener(new AnimationListener() {
        public void onAnimationStart(Animation anim){};
        public void onAnimationRepeat(Animation anim){};
        public void onAnimationEnd(Animation anim){
            //l.setLayoutParams(params);
        };
    });
l.startAnimation(a);
  

Когда анимация будет завершена, я бы хотел, чтобы анимированное линейное описание переместилось в новую позицию (куда его переместила анимация). Причина этого в том, что LinearLayout содержит несколько элементов формы, с которыми пользователь может взаимодействовать.

Это действительно простая анимация для довольно простого проекта. Это просто перемещает элемент примерно на 30 пикселей вниз по экрану. Я бы не стал просить о помощи, если бы не боролся с этим уже несколько часов. Я знаю, что мне нужно обновить параметры линейного описания в конце анимации, но как именно? Я читал о нескольких разных способах, и все они немного сбивают с толку.

Заранее спасибо.

Ответ №1:

Вместо создания нового AnimationListener попробуйте реализовать AnimationListener интерфейс для вашего текущего (или нового) класса. Затем просто переопределите onAnimationEnd() метод.

Пример:

 public class ThisClass implements AnimationListener {

      private otherMethod() {
          l.getAnimation().setAnimationListener(this);
      }

      public void onAnimationStart(Animation anim){};
      public void onAnimationRepeat(Animation anim){};
      public void onAnimationEnd(Animation anim){
          l.setLayoutParams(params);
      };
  

}

Комментарии:

1. Казалось бы, это имеет смысл. Я расширил calss с помощью AnimationListener, как вы указывали, и добавил необходимые методы прослушивания. За исключением того, что «параметры» не могут быть преобразованы в переменную в методе onAnimationEnd. Что вы имели в виду под этим? На что будут ссылаться параметры?

2. И l.getAnimation().setAnimationListener(this); сбой моего приложения 🙁

3. вам нужно создать новую переменную LayoutParams или же создать одну общедоступную для класса. Почему происходит сбой (что сказал logcat)?

4. a.setAnimationListener(this); Установка параметров LAYOUT и передача значений — это то, что меня смущает. Я не знаю, как настроить таргетинг на новую позицию для установки моего LinearLayout, или это вообще то, что я должен делать.

Ответ №2:

Наконец-то есть способ обойти, правильный способ сделать это setFillAfter(true) ,

если вы хотите определить свою анимацию в xml, вам следует сделать что-то вроде этого

 <set xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@android:anim/decelerate_interpolator"
     android:fillAfter="true">

    <translate 
        android:fromXDelta="0%"
        android:toXDelta="-100%"
        android:duration="1000"/>

</set>
  

вы можете видеть, что я определил filterAfter="true" в set теге, если вы попытаетесь определить это в translate теге, это не сработает, возможно, это ошибка во фреймворке!!

и затем в коде

 Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out);
someView.startAnimation(anim);
  

или

 TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0);

            animation.setFillAfter(true);

            animation.setDuration(1800);

            someView.startAnimation(animation);
  

тогда это обязательно сработает!!

Теперь это немного сложно, кажется, что вид на самом деле перемещается в новую позицию, но на самом деле пиксели вида перемещаются, т. Е. ваш вид фактически находится в исходном положении, но не виден, вы можете проверить это, если у вас есть какая-либо кнопка или интерактивное представление в вашем представлении (в моем случае в макете), чтобы исправить это, вам нужно вручную переместить свой вид / макет в новое положение

 public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)

new TranslateAnimation(-90, 150, 0, 0);
  

теперь, как мы можем видеть, наша анимация будет начинаться с -90 оси x до 150 оси x

итак, что мы делаем, это устанавливаем

 someView.setAnimationListener(this);
  

и в

 public void onAnimationEnd(Animation animation)
{
   someView.layout(150, 0, someView.getWidth()   150, someView.getHeight());
}
  

теперь позвольте мне объяснить public void layout (int left, int top, int right, int botton)

это перемещает ваш макет в новую позицию первый аргумент определяет левую сторону, которая у нас равна 150, потому что translate animation анимировала наш вид по оси 150 x, top равен 0, потому что мы не анимировали ось y, теперь справа, что мы сделали someView.getWidth() 150 в основном, мы получаем ширину нашего вида и добавили 150, потому что мы теперь перемещаем нашу левую сторону на ось 150 x, чтобы сделать ширину вида равной исходной, а нижняя равна высоте нашего вида.

Я надеюсь, что теперь вы поняли концепцию перевода, и у вас все еще есть какие-либо вопросы, которые вы можете задать сразу в разделе комментариев, я с удовольствием помогу 🙂

РЕДАКТИРОВАТЬ Не используйте layout() метод, поскольку он может быть вызван фреймворком, когда любой просмотр недействителен и ваши изменения не будут сохранены, используйте LayoutParams для настройки параметров макета в соответствии с вашими требованиями