Я изо всех сил пытаюсь заставить ConstraintLayout работать на меня, когда я хочу реорганизовать общий код макета в отдельный файл XML. Я легко могу сделать это с помощью RelativeLayouts, но я считаю, что RelativeLayouts устарели, и мы должны сейчас использовать ConstraintLayous.
У меня есть приложение с экраном, который имеет разную компоновку на портретной и альбомной ориентациях, как показано на диаграмме ниже.
У меня есть 2 файла макета с одинаковым именем («my_layout.xml»), один в папке «layout» и один в «layout-земля". В настоящее время я продублировал все xml в обоих файлах макета и скорректировал ограничения так, чтобы в альбомной версии виды располагались горизонтально.
Портретная версия
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- OTHER VIEWS 1 -->
<View
android:id="@+id/OtherViews1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- OTHER VIEWS 2 -->
<View
android:id="@+id/OtherViews2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottom="@+id/OtherViews1"
app:layout_constraintBottom_toTopOf="@+id/scrollbar" />
<!-- SCROLL BAR VIEWS -->
<TextView
android:id="@+id/slow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="@+id/scrollbar"
app:layout_constraintBottom_toBottomOf="@+id/scrollbar"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/scrollbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
...
app:layout_constraintBottom_toTopOf="@+id/OtherViews3"
app:layout_constraintStart_toEndOf="@+id/slow"
app:layout_constraintEnd_toStartOf="@+id/fast"/>
<TextView
android:id="@+id/fast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="@+id/scrollbar"
app:layout_constraintBottom_toBottomOf="@+id/scrollbar"
app:layout_constraintStartEnd_toEndOf="parent" />
<!-- OTHER VIEWS 3 -->
<View
android:id="@+id/OtherViews3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Пейзажная версия
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- OTHER VIEWS 1 -->
<View
android:id="@+id/OtherViews1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- OTHER VIEWS 2 -->
<View
android:id="@+id/OtherViews2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottom="@+id/OtherViews1"
app:layout_constraintBottom_toBottomOf="parent" />
<!-- SCROLL BAR VIEWS -->
<TextView
android:id="@+id/slow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintStart_toEndOf="@+id/OtherViews2"
app:layout_constraintTop_toTopOf="@+id/scrollbar"
app:layout_constraintBottom_toBottomOf="@+id/scrollbar"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/scrollbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
...
app:layout_constraintBottom_toTopOf="@+id/OtherViews3"
app:layout_constraintStart_toEndOf="@+id/slow"
app:layout_constraintEnd_toStartOf="@+id/fast"/>
<TextView
android:id="@+id/fast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="@+id/scrollbar"
app:layout_constraintBottom_toBottomOf="@+id/scrollbar"
app:layout_constraintStartEnd_toEndOf="parent" />
<!-- OTHER VIEWS 3 -->
<View
android:id="@+id/OtherViews3"
android:layout_width="wrap_content"
android:layout_height="wrap_content
app:layout_constraintStart_toEndOf="@+id/OtherViews2""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
XML для текстового поля «Медленный», полосы прокрутки и текстового поля «Быстрый» дублируется в обоих файлах. Я хотел бы переместить макет для этих 3 элементов в отдельный файл и сослаться на него в обоих файлах "my_layout.xml", чтобы его можно было многократно использовать и не дублировать файлы макета. Я хочу сохранить мою иерархию плоской (в противном случае я бы просто использовал RelativeLayouts). Я не знаю, как указать ограничения для нового многоразового XML-файла макета для пользовательского интерфейса полосы прокрутки.
Портретная версия с многократным использованием макета полосы прокрутки
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- OTHER VIEWS 1 -->
<View
android:id="@+id/OtherViews1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- OTHER VIEWS 2 -->
<View
android:id="@+id/OtherViews2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottom="@+id/OtherViews1"
app:layout_constraintBottom_toTopOf="@+id/scrollbar" />
<include
layout="@layout/scrollbar
app:layout_constraintBottom_toTopOf="@+id/OtherViews3"
app:layout_constraintStart_toStartOf="parent" />
<!-- OTHER VIEWS 3 -->
<View
android:id="@+id/OtherViews3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Многоразовый макет полосы прокрутки
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!-- SCROLL BAR VIEWS -->
<TextView
android:id="@+id/slow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="@+id/scrollbar"
app:layout_constraintBottom_toBottomOf="@+id/scrollbar"
app:layout_constraintStart_toStartOf="parent"/> ******************
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/scrollbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
...
app:layout_constraintBottom_toTopOf="@+id/OtherViews3" ******************
app:layout_constraintStart_toEndOf="@+id/slow"
app:layout_constraintEnd_toStartOf="@+id/fast"/>
<TextView
android:id="@+id/fast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="@+id/scrollbar"
app:layout_constraintBottom_toBottomOf="@+id/scrollbar"
app:layout_constraintStartEnd_toEndOf="parent" /> ******************
</androidx.constraintlayout.widget.ConstraintLayout>
Я не знаю, что поставить для линий, отмеченных ****. Если я укажу, что «медленное» текстовое поле начинается в начале родительского, это не будет работать для альбомной версии. Я хотел бы, чтобы этот макет полосы прокрутки просто указывал на медленную слева, полосу прокрутки посередине (занимая все оставшееся пространство) и быстрое текстовое поле справа. Как мне это сделать с помощью Constraint Layout? Кроме того, как мне центрировать все 3 вида по вертикали?
RelativeLayout намного проще, как я бы сказал, медленное текстовое полеэто выровненный родительский элемент, быстрый - выровненный родительский, а полоса прокрутки находится справа от медленного текстового поля и слева от быстрого текстового поля. Наконец, я бы сказал, что все 3 вида расположены по центру родительского элемента.