Как располагаются элементы во FrameLayout в Android
Что проверяют
Знаете ли вы, что FrameLayout складывает детей стопкой, и чем управляются их положение и порядок отрисовки. Следом часто спрашивают, почему кнопка вдруг оказалась поверх элемента, объявленного позже, или чем FrameLayout отличается от ConstraintLayout.
Как отвечать
- наложение: все дочерние элементы рисуются в одной области друг поверх друга в порядке добавления. Первый в XML оказывается внизу, последний сверху. Программно порядок меняют
addViewс индексом илиbringToFront(); - позиция по умолчанию: без указаний ребёнок прижимается к левому верхнему углу, точнее к
top|start. Сдвигают его атрибутомandroid:layout_gravityу самого ребёнка:center,bottom|endи комбинации. Отступы задаются черезlayout_margin, аpaddingконтейнера сжимает область сразу для всех; - размер: при
wrap_contentконтейнер становится по размеру самого большого ребёнка с учётом отступов. Элементы сvisibility="gone"в расчёт не идут, если не выставитьandroid:measureAllChildren="true"; - ось Z: с API 21 порядок отрисовки зависит ещё и от
elevationиtranslationZ. Элемент с большим Z рисуется поверх, даже если объявлен раньше; - где применяется: оверлеи (картинка с подписью, индикатор загрузки поверх контента), контейнер под один экран.
FragmentContainerView, который рекомендуют для фрагментов, сам наследуетFrameLayout.
Хорошо добавить, что в Compose аналог это Box: наложение в порядке объявления, положение через Modifier.align, порядок по оси Z через Modifier.zIndex.
Где спотыкаются
Путают android:gravity и android:layout_gravity. Первый управляет содержимым самой вью, второй положением ребёнка в контейнере.
Не знают про elevation. Material-кнопка по умолчанию приподнята, поэтому рисуется поверх TextView, объявленного ниже в XML. Лечится через translationZ у нужного элемента или android:stateListAnimator="@null" у кнопки.
Строят сложный экран на FrameLayout, расставляя элементы жёсткими отступами. Он нужен для наложения, а раскладку элементов относительно друг друга лучше отдать ConstraintLayout.