Я пытаюсь использовать ConstraintLayout
в сочетании с видами, которые скользят вверх и вниз с анимацией.Эти виды организованы вертикально, с RecyclerView
вверху и двумя другими представлениями, сложенными под ним:
<constraint layout container>
[ ]
[ recycler view ]
[ ]
[48dp height 1st view]
[48dp height 2nd view]
</constraint layout container>
Анимация очень проста: при нажатии кнопки 1-й вид перемещается снизуконтейнер в положение, которое вы видите выше, при повторном нажатии он перемещается вниз и остается наложенным на 2-й вид.Когда это происходит, RecyclerView
в верхней части изменяет высоту, поскольку ограничено этим первым видом, в противном случае он оставит пустое пространство.
Пока все хорошо, и анимация работает хорошо, но возникает проблемакогда пользователь нажимает кнопку слишком быстро, что приводит к следующей ошибке:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
После изучения происходящего я обнаружил, что эта проблема является следствием TransitionManager
, который я использую для анимацииизменения.То, что я обнаружил, было интересно, когда кнопка была нажата, чтобы переместить 1-й вид вверх (или вниз, просто представьте себе противоположные шаги), менеджер делал следующее:
- Исчезает первый / последний видиз
RecyclerView
(зависит от того, включен ли у вас обратный макет или стек с конца) - Удалите это представление из
RecyclerView
- Уменьшите высоту
RecyclerView
- Переместить 1-й вид вверх
Несмотря на то, что я указал во всех местах, я мог представить, что RecyclerView
не должен анимировать изменения элемента, TransitionManager
переопределяет его иэто означало, что есть окно, в котором тот же самый вид, который собирается удалить из RecyclerView
, может быть снова добавлен к тому же родительскому элементу, и это окно - когда представление исчезает из менеджера.
Поскольку анимация затухания не такая быстрая, пользователь может очень легко дважды нажать кнопку в течение этого времени, заставляя менеджера повторно добавить вид затухания, который уже находится в RecyclerView
, и, таким образом,озоление приложения при выдаче вышеуказанной ошибки.
Так как это проблема, вызванная внутри RecyclerView
, я буду прекрасно работать без анимации внутри, и по этой причине я хотел бы знать, как я могу указать вTransitionManager.beginDelayedTransition
только для анимации прямых дочерних представлений ConstraintLayout
, таким образом, он не будет анимировать представления внутри RecyclerView
.
Соответствующая документация ничего не освещает, поэтому я представляювот этот вопрос;Как я могу ограничить переход к прямым дочерним видам?
В случае, если это может быть полезно, я включу сюда фрагмент менеджера переходов
final ConstraintSet constraintSet;
final ConstraintLayout constraintLayout;
constraintSet = new ConstraintSet();
constraintLayout = (ConstraintLayout) viewParent;
TransitionManager.beginDelayedTransition(constraintLayout);
constraintSet.clone(constraintLayout);
constraintSet.connect(startId, startSide, endId, endSide, margin);
constraintSet.applyTo(constraintLayout);