Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Анимация setVisibility GONE/VISIBLE

#java #android #android_animation


Как сделать, чтобы при скрытии нескольких View-элементов, находящихся рядом в LinearLayout
было так:  


View-элементы одновременно плавно выцветают.
Все, что было под ними, плавно сдвигается вверх на их место.


И аналогично для setVisibility(View.VISIBLE).

Пробовал использовать animateLayoutChanges="true" - не срабатывает.



UPD:
animateLayoutChanges="true" не срабатывало только в ScrollView, после перенесения
этого атрибута в LinearLayout все получилось.
    


Ответы

Ответ 1



Задачу можно решить с помощью ViewPropertyAnimator. Возьмем для примера LinearLayout с тремя элементами: Как бы мы сделали без анимации? two.setVisibility(View.GONE); Что это дает? Элемент two исчезает, элемент three смещается наверх на место two. Какая нам нужна анимация? Сначала у элемента two плавно уменьшить прозрачность, затем элемент three плавно сместить наверх на высоту элемента two. Так и запишем: void stepOne() { two.animate() .setDuration(500) .alpha(0) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { stepTwo(); } }); } void stepTwo() { three.animate() .setDuration(500) .translationY(-binding.two.getHeight()) .setInterpolator(new AccelerateInterpolator()) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { stepThree(); } }); } /* нужно в конце анимаци вернуть свойства в исходное состояние, но так, чтобы взаимное расположение осталось неизменным */ void stepThree() { // отключаем лиснеры, на всякий случай, чтобы при следующей анимации неожиданно не сработал three.animate().setListener(null); two.animate().setListener(null); // сводим задачу к предыдущей two.setVisibility(View.GONE); // возвращаем свойства в исходное состояние three.setTranslationY(0); binding.two.setAlpha(1); } При наступлении события надо запустить stepOne(). Надо ли чистить последствия анимации на третьем шаге - решать вам. Если это разовый эффект, то надо, чтобы дальнейшая работа с интерфейсом не была неожиданной, потому что, например, элемент three так и останется смещенным относительно своего исходного положения. Если же все поведение интерфейса будет построено на анимации, то не надо, чтобы появление элемента two обратно можно было сделать аналогично исчезновению. Про эту анимацию была статья в блоге: https://android-developers.googleblog.com/2011/05/introducing-viewpropertyanimator.html Еще один пример использования этй же анимации есть в моей статье: http://jollydroid.ru/notebook/2016-04-05-Property-Animation-Rotation.html

Ответ 2



Достаточно использовать animateLayoutChanges="true". Чтобы оно работало нужно использовать linearLayout.addView(view) чтобы добавить вьюшку с анимацией и чтобы удалить linearlayout.removeView(view). В разделе "Курсы" есть статья: https://developer.android.com/training/animation/layout.html

Ответ 3



Второй способ решения этой задачи - поменять LinearLayout на RecyclerView. Тогда можно исчезновение и появление сделать с помощью RecyclerView.ItemAnimator - написать свой или взять готовый. Тогда получится универсальное решение, которое одинаково красиво покажет исчезновение или появление любого количества элементов. Аниматор можно оставить стандартный или найти в сторонней библиотеке: https://github.com/wasabeef/recyclerview-animators

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

Отправить комментарий