AnimateLayoutChanges не работает с вложенным макетом?
У меня есть вложенный макет, как показано ниже:
<LinearLayout> <!----Parent layout--->
<LinearLayout> <!-----child 1--->
...
</LinearLayout> <!----child 1 ended--->
<LinearLayout> <!-----child 2--->
...
</LinearLayout> <!----child 2 ended--->
</LinearLayout> <!----Parent endded--->
Проблема, с которой я столкнулся сейчас, заключается в том, что, поскольку все мои элементы данных находятся в дочернем 1 или дочернем 2 Linearlayout
, если я добавляю или удаляю элемент, дочерний linearlayout будет анимировать с эффектом animateLayoutChanges, но родительский макет не будет сделать любую анимацию. (У меня android:animateLayoutChanges
установлен на true
для всех линейных макетов). Особенно, когда я удаляю элемент в дочернем 1, эффект анимации становится странным (в основном ребенок 2 будет прыгать, пока ребенок 1 все еще делает свою анимацию).
Кто-нибудь знает, как это решить?
Спасибо
UPDATE
Вскоре после того, как я разместил этот вопрос, я нашел это на сайте разработчиков Android в API LayoutTransition.
Использование LayoutTransition на нескольких уровнях иерархии вложенных представлений может не работать из-за взаимосвязи различных уровней макета.
У кого-нибудь есть какие-либо проблемы с предложениями по этой проблеме?
Ответы
Ответ 1
Свойство animateLayoutChanges
использует LayoutTransitions
, которые оживляют как дочерние элементы макета, так и от Android 4.0 вперед, предков иерархии макета вплоть до вершины дерева. В Honeycomb будут только анимированные макеты. Подробнее см. эту статью в блоге разработчиков Android.
К сожалению, кажется, что в настоящее время нет простого способа, чтобы братья и сестры макета реагировали на его LayoutTransitions
. Вы можете попробовать использовать TransitionListener
, чтобы получить уведомление, когда границы макета будут изменены, и соответственно переместить представления для сестер с помощью Animators. См. Второй ответ на сообщение Чет Хаазе в этой публикации в Google+.
EDIT. Оказывается, есть способ. В Android 4.1+ (API-уровень 16+) вы можете использовать тип перехода макета CHANGING
, который по умолчанию отключен. Чтобы включить его в код:
ViewGroup layout = (ViewGroup) findViewById(R.id.yourLayout);
LayoutTransition layoutTransition = layout.getLayoutTransition();
layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
Итак, в вашем примере, чтобы анимировать макет child 2, вам нужно включить для него преобразование макета CHANGING
. Преобразование затем будет применяться, когда происходит изменение границ его родителя.
Подробнее см. это видео DevBytes.
Ответ 2
Кажется, что отложенный переход на родителя также работает для анимации. По крайней мере, для меня следующий код дает правильную анимацию expand/collapse.
expandTrigger.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TransitionManager.beginDelayedTransition(parentLayout);
expanded = !expanded;
child1.setVisibility(expanded ? View.VISIBLE : View.GONE);
}
});
Для глубоко вложенных макетов вам иногда может понадобиться использовать родителя выше в иерархии при вызове TransitionManager
.
Ответ 3
Мы добавили атрибут android: animateLayoutChanges в наш LinearLayout, но изменение не вызвало анимацию. Чтобы исправить это, используйте этот код:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
((ViewGroup) findViewById(R.id.llRoot)).getLayoutTransition()
.enableTransitionType(LayoutTransition.CHANGING);
}
Подробнее.