Проблема в том, что «сдвиг» остальных элементов происходит из‑за изменения layout (виды меняют видимость / высоту / margin) — ScrollView перестраивает дочерние вью, и всё перетасовывается. Решения сводятся к двум подходам: не трогать layout во время анимации, либо выполнять анимацию визуально поверх layout.
Коротко — что сделать:
1) Анимируйте свойства, не влияющие на измерения (translationX/Y, alpha, scale). Такие анимации не вызывают перерасчёт расположения и не сдвинут соседей.
- Показывать: заранее сделать view.VISIBLE, поставить начальный translationY/alpha и анимировать к нулю/1.
- Скрывать: анимировать translationY/alpha и в withEndAction() установить visibility = INVISIBLE (а не GONE), если нужно сохранить занимаемое место. Если же ставите GONE — будет перерасчёт и сдвиг.
Пример (Java):
```java
// Показать
view.setVisibility(View.VISIBLE);
view.setAlpha(0f);
view.setTranslationY(30f);
view.animate().alpha(1f).translationY(0f).setDuration(200).start();
// Скрыть (без перерасчёта layout)
view.animate().alpha(0f).translationY(30f).setDuration(200)
.withEndAction(() -> view.setVisibility(View.INVISIBLE)).start();
```
2) Если нужно, чтобы элемент физически исчезал (GONE) но при этом не было визуального сдвига во время анимации — выполнять анимацию на наложении (ViewGroupOverlay) или в отдельном контейнере поверх ScrollView (FrameLayout над ScrollView). Тогда вы анимируете копию/overlay и в конце проставляете GONE для реального элемента.
3) Убедитесь, что у родителя не включена автоматическая анимация layout (android:animateLayoutChanges="true" или LayoutTransition). Она заставляет родителя плавно перестраивать дочерние и может давать нежелательные сдвиги. Отключите:
```java
((ViewGroup) parent).setLayoutTransition(null);
```
4) Если вы сознательно хотите изменять размеры и чтобы остальные элементы плавно адаптировались — используйте ValueAnimator для анимирования высоты и вызывайте requestLayout() (или TransitionManager.beginDelayedTransition для плавной смены constraint), но это именно перерасчёт layout и элементы будут двигаться.
Резюме:
- Если НЕ нужно, чтобы соседние элементы двигались — анимируйте translation/alpha (или используйте overlay) и не выставляйте GONE во время анимации.
- Если нужно реальное изменение размера/визибилити — тогда придется позволить перерасчёт, либо управлять этим через анимированный overlay/placeholder, чтобы избежать резких сдвигов.