Перевод статьи на Медиуме о построении пользовательского интерфейса с помощью компонента разметки ConstraintLayout.
Создайте сложный и отзывчивый интерфейс для вашего приложения
ConstraintLayout был представлен для создания очень сложных и отзывчивых пользовательских интерфейсов приложений. Ранее я использовал RelativeLayout для создания сложных пользовательских интерфейсов, пока не наткнулся на этот интерфейс.
Снимок экрана выше – это футер фрагмента в нижней части экрана приложения, который описывает шаги процесса входа в систему и на каком этапе находится пользователь.
Есть три шага для завершения входа в систему.
- Mobile Number
- OTP
- Profile
В настоящее время пользователь находится на первом шаге, а именно «введите номер мобильного телефона».
Потратьте несколько минут и попробуйте создать описанный выше пользовательский интерфейс, используя RelativeLayout или любой другой макет, и посмотрите, как он работает. Дайте мне знать в комментариях, если вы смогли построить именно этот пользовательский интерфейс, используя макет, отличный от ConstraintLayout.
Те, кто не знаком с ConstraintLayout, сначала должны прочитать документацию по Android ConstraintLayout.
Давайте начнем.
Внедрение ConstraintLayout в проект
Сначала добавьте зависимость Gradle в ваш проект.
dependencies { implementation 'com.android.support.constraint:constraint-layout:1.1.2' }
Использование Guideline
Так выглядит пользовательский интерфейс, о котором пойдет речь ниже, в режиме конструктора в Android Studio.
Создание этого интерфейса стало возможным благодаря использованию Guideline.
Guideline — это аналог линии, устанавливаемой на макетах в визуальных редакторах, по которой дизайнеры выравнивают элементы. Такую линию представляет view класса
android.support.constraint.Guideline
. Guideline может быть горизонтальным или вертикальным — это указывается атрибутомandroid:orientation
. Сам guideline нулевого размера, не занимает места в контейнере и всегда привязан только к сторонам ConstraintLayout.
Guideline – это не что иное, как виртуальные представления – они не видны как таковые. Их можно просматривать в превью дизайна и blueprints. На изображении выше вы можете видеть, что я использовал два ориентира – две пунктирные линии, которые можно увидеть в центре по вертикали и по горизонтали.
После добавления Guideline , вот как выглядит XML:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="80dp" android:paddingBottom="8dp"> <android.support.constraint.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.5" /> <android.support.constraint.Guideline android:id="@+id/guideline1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.5" /> </android.support.constraint.ConstraintLayout>
Строка app:layout_constraintGuide_percent=”0.5"
определяет, где именно вы хотите установить Guideline. В моем случае я хотел, чтобы это было в центре, поэтому установил значение 0,5.
Если вы хотите добавить TextView горизонтально, например, точно на 3/4 ширины экрана, вам нужно добавить вертикальную направляющую. Это действительно было бы вертикальным ориентиром. Мы делим экран по горизонтали, поэтому будем использовать vertical guideline.
Это будет выглядеть следующим образом:
<android.support.constraint.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.75" />
Надеюсь, что это дает вам представление о Guideline. Мы вернемся к исходной проблеме сейчас.
После добавления двух направляющих Guideline – по горизонтали и по вертикали, точно по центру – добавим первый элемент пользовательского интерфейса.
Добавление ImageView
Во-первых, мы добавим ImageView точно в центр Guideline. Вот код:
<ImageView android:id="@+id/ivotp" android:layout_width="16dp" android:layout_height="16dp" android:layout_marginTop="8dp" android:background="@drawable/otp_process_circle" app:layout_constraintBottom_toTopOf="@+id/guideline1" app:layout_constraintEnd_toStartOf="@+id/guideline" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toTopOf="@+id/guideline1" />
Разместить ваш ImageView точно по центру относительно горизонтальной направляющей помогают следующие строки:
app:layout_constraintBottom_toTopOf="@+id/guideline1" app:layout_constraintTop_toTopOf="@+id/guideline1"
А разместить ImageView точно по центру относительно вертикальной направляющей помогают следующие строки:
app:layout_constraintEnd_toStartOf="@+id/guideline" app:layout_constraintStart_toStartOf="@+id/guideline"
Теперь мы добавим разделители слева и справа от этого ImageView, как того требует пользовательский интерфейс:
<ImageView android:id="@+id/ivseconddiv" android:layout_width="76dp" android:layout_height="2dp" android:background="@drawable/stroke_divider" android:layerType="software" app:layout_constraintBottom_toBottomOf="@+id/ivotp" app:layout_constraintStart_toEndOf="@+id/ivotp" app:layout_constraintTop_toTopOf="@+id/ivotp" /> <ImageView android:id="@+id/ivfirstdiv" android:layout_width="76dp" android:layout_height="2dp" android:layerType="software" android:src="@drawable/stroke_divider" app:layout_constraintBottom_toBottomOf="@+id/ivotp" app:layout_constraintEnd_toStartOf="@+id/ivotp" app:layout_constraintTop_toTopOf="@+id/ivotp" />
Строки ниже помещают разделитель точно по центру по вертикали относительно ImageView ivotp:
app:layout_constraintBottom_toBottomOf
app:layout_constraintTop_toTopOf
Вот как выглядит наш пользовательский интерфейс:
В конце этих разделителей мы добавим два ImageViews, как показано ниже:
<ImageView android:id="@+id/ivnumberfill" android:layout_width="16dp" android:layout_height="16dp" app:layout_constraintBottom_toBottomOf="@+id/ivfirstdiv" app:layout_constraintEnd_toStartOf="@+id/ivfirstdiv" app:layout_constraintTop_toTopOf="@+id/ivfirstdiv" app:srcCompat="@drawable/ic_otp_fill" /> <ImageView android:id="@+id/ivprofile" android:layout_width="16dp" android:layout_height="16dp" android:layout_toRightOf="@+id/ivseconddiv" android:background="@drawable/otp_process_circle" app:layout_constraintBottom_toBottomOf="@+id/ivseconddiv" app:layout_constraintStart_toEndOf="@+id/ivseconddiv" app:layout_constraintTop_toTopOf="@+id/ivseconddiv" />
Вот как выглядит наш пользовательский интерфейс:
Теперь нам просто нужно добавить три TextView под каждым кругом ImageView, точно в центре по горизонтали. Вот код, чтобы добавить это:
<TextView android:id="@+id/tvnumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ivnumberfill" android:layout_marginTop="4dp" android:text="Mobile Number" android:textColor="?colorAccent" android:textSize="11sp" app:layout_constraintEnd_toEndOf="@id/ivnumberfill" app:layout_constraintStart_toStartOf="@id/ivnumberfill" app:layout_constraintTop_toBottomOf="@id/ivnumberfill" /> <TextView android:id="@+id/tvotp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ivnumberfill" android:layout_marginTop="8dp" android:text="OTP" android:textColor="#949595" android:textSize="11sp" app:layout_constraintEnd_toStartOf="@+id/ivseconddiv" app:layout_constraintStart_toStartOf="@+id/ivotp" app:layout_constraintTop_toBottomOf="@+id/ivotp" /> <TextView android:id="@+id/tvprofile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ivnumberfill" android:layout_marginTop="8dp" android:text="Profile" android:textColor="#949595" android:textSize="11sp" app:layout_constraintEnd_toEndOf="@+id/ivprofile" app:layout_constraintStart_toStartOf="@+id/ivprofile" app:layout_constraintTop_toBottomOf="@+id/ivprofile" />
В приведенном выше коде строки app: layout_constraintEnd_toEndOf
и app: layout_constraintStart_toStartOf
выровняют текст по горизонтали относительно ImageView, а строка app: layout_constraintTop_toBottomOf
выровняет текст под ImageView.
Финальный результат и код
Вот наш пользовательский интерфейс и наш окончательный код XML:
<android.support.constraint.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="80dp" android:paddingBottom="8dp"> <ImageView android:id="@+id/ivotp" android:layout_width="16dp" android:layout_height="16dp" android:layout_marginTop="8dp" android:background="@drawable/otp_process_circle" app:layout_constraintBottom_toTopOf="@+id/guideline1" app:layout_constraintEnd_toStartOf="@+id/guideline" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toTopOf="@+id/guideline1" /> <ImageView android:id="@+id/ivseconddiv" android:layout_width="76dp" android:layout_height="2dp" android:background="@drawable/stroke_divider" android:layerType="software" app:layout_constraintBottom_toBottomOf="@+id/ivotp" app:layout_constraintStart_toEndOf="@+id/ivotp" app:layout_constraintTop_toTopOf="@+id/ivotp" /> <ImageView android:id="@+id/ivfirstdiv" android:layout_width="76dp" android:layout_height="2dp" android:layerType="software" android:src="@drawable/stroke_divider" app:layout_constraintBottom_toBottomOf="@+id/ivotp" app:layout_constraintEnd_toStartOf="@+id/ivotp" app:layout_constraintTop_toTopOf="@+id/ivotp" /> <ImageView android:id="@+id/ivnumberfill" android:layout_width="16dp" android:layout_height="16dp" app:layout_constraintBottom_toBottomOf="@+id/ivfirstdiv" app:layout_constraintEnd_toStartOf="@+id/ivfirstdiv" app:layout_constraintTop_toTopOf="@+id/ivfirstdiv" app:srcCompat="@drawable/ic_otp_fill" /> <ImageView android:id="@+id/ivprofile" android:layout_width="16dp" android:layout_height="16dp" android:layout_toRightOf="@+id/ivseconddiv" android:background="@drawable/otp_process_circle" app:layout_constraintBottom_toBottomOf="@+id/ivseconddiv" app:layout_constraintStart_toEndOf="@+id/ivseconddiv" app:layout_constraintTop_toTopOf="@+id/ivseconddiv" /> <TextView android:id="@+id/tvnumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ivnumberfill" android:layout_marginTop="4dp" android:text="Mobile Number" android:textColor="?colorAccent" android:textSize="11sp" app:layout_constraintEnd_toEndOf="@id/ivnumberfill" app:layout_constraintStart_toStartOf="@id/ivnumberfill" app:layout_constraintTop_toBottomOf="@id/ivnumberfill" /> <TextView android:id="@+id/tvotp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ivnumberfill" android:layout_marginTop="8dp" android:text="OTP" android:textColor="#949595" android:textSize="11sp" app:layout_constraintEnd_toStartOf="@+id/ivseconddiv" app:layout_constraintStart_toStartOf="@+id/ivotp" app:layout_constraintTop_toBottomOf="@+id/ivotp" /> <TextView android:id="@+id/tvprofile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/ivnumberfill" android:layout_marginTop="8dp" android:text="Profile" android:textColor="#949595" android:textSize="11sp" app:layout_constraintEnd_toEndOf="@+id/ivprofile" app:layout_constraintStart_toStartOf="@+id/ivprofile" app:layout_constraintTop_toBottomOf="@+id/ivprofile" /> <android.support.constraint.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.5" /> <android.support.constraint.Guideline android:id="@+id/guideline1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.5" /> </android.support.constraint.ConstraintLayout>
После создания этого интерфейса я понимаю важность использования ConstraintLayout. Теперь я стараюсь использовать ConstraintLayout везде, где это возможно.