Рівномірно розташований вид з використанням ConstraintLayout


174

Загальне використання - LinearLayoutце рівномірна (вагова) кількість поглядів, наприклад: Приклад компонування

Як ви реалізуєте рівномірно розміщені погляди на кшталт цього за допомогою нового ConstraintLayout?

ConstraintLayoutпосилання для довідки: публікація в блозі , відео сеансу вводу / виводу

Відповіді:


323

Це можна досягти двома способами ConstraintLayout: ланцюги та вказівки . Щоб використовувати ланцюги, переконайтеся, що ви використовуєте ConstraintLayoutBeta 3 або новішу версію, а якщо ви хочете використовувати редактор візуального макета в Android Studio, переконайтеся, що ви використовуєте Android Studio 2.3 Beta 1 або новішу версію.

Спосіб 1 - Використання ланцюгів

Відкрийте редактор макетів і додайте свої віджети як звичайні, додаючи батьківські обмеження за потребою. У цьому випадку я додав дві кнопки з обмеженнями в нижній частині материнської та збоку батьків (ліва сторона для кнопки "Зберегти", а права - для кнопки "Поділитися"):

введіть тут опис зображення

Зауважте, що в такому стані, якщо я перевернувся на краєвидний вигляд, представлення не заповнюють батьківську, а прив’язані до кутів:

введіть тут опис зображення

Виділіть обидва види перегляду або клацанням Ctrl / Cmd, або перетягуванням поля навколо переглядів:

введіть тут опис зображення

Потім клацніть правою кнопкою миші перегляд і виберіть "По горизонталі по центру":

введіть тут опис зображення

Це встановлює двосторонній зв'язок між видами (саме так визначається ланцюжок). За замовчуванням стиль ланцюга - "розповсюдження", який застосовується навіть тоді, коли атрибут XML не включений. Дотримуючись цього стилю ланцюга, але встановлюючи ширину наших поглядів, щоб перегляди 0dpдозволяли заповнити наявний простір, рівномірно розподіляючись по батьківському:

введіть тут опис зображення

Це помітніше в пейзажному вигляді:

введіть тут опис зображення

Якщо ви віддаєте перевагу пропустити редактор макета, отриманий 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="match_parent">

<Button
    android:id="@+id/button_save"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="@string/button_save_text"
    android:layout_marginStart="8dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="4dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/button_share"
    app:layout_constraintHorizontal_chainStyle="spread" />

<Button
    android:id="@+id/button_share"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="@string/button_share_text"
    android:layout_marginStart="4dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp"
    app:layout_constraintLeft_toRightOf="@+id/button_save"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintBottom_toBottomOf="parent" />

</android.support.constraint.ConstraintLayout>

Деталі:

  • встановлення ширини кожного елемента 0dpабо MATCH_CONSTRAINTдозволяє переглядам заповнювати батьківський (необов'язково)
  • перегляди повинні бути пов’язані між собою двосторонньо (праворуч на збереження посилань кнопки спільного використання на кнопку спільного доступу, ліворуч від посилань на кнопку спільного доступу, щоб зберегти кнопку), це відбудеться автоматично через редактор макета, вибираючи "Центр горизонтально"
  • перший погляд у ланцюжку може вказати стиль ланцюга через layout_constraintHorizontal_chainStyle, перегляньте документацію для різних стилів ланцюга, якщо стиль ланцюга опущено, за замовчуванням є "розповсюдження"
  • вагу ланцюга можна регулювати за допомогою layout_constraintHorizontal_weight
  • цей приклад для горизонтального ланцюга, є відповідні атрибути для вертикальних ланцюгів

Спосіб 2 - Використання Керівництва

Відкрийте ваш макет у редакторі та натисніть кнопку орієнтиру:

введіть тут опис зображення

Потім виберіть "Додати вертикальну інструкцію": введіть тут опис зображення

З'явиться нова настанова, яка за замовчуванням, ймовірно, буде прикріплена ліворуч у відносних значеннях (позначається лівою стрілкою):

відносна інструкція редактора макетів

Клацніть стрілку ліворуч, щоб переключити її на процентне значення, а потім перетягніть орієнтир до позначки 50%:

відсоткове керівництво редактора макета

Настанова тепер може використовуватися як прив'язка до інших поглядів. У своєму прикладі я додав праворуч від кнопки збереження та ліворуч від кнопки спільного доступу до настанови:

остаточний макет

Якщо ви хочете, щоб види переповнювали доступний простір, тоді обмеження має бути встановлено на "Будь-який розмір" (чіткі лінії, розташовані горизонтально):

будь-яке обмеження розміру

(Це те саме, що встановити layout_widthна 0dp).

Настанова також може бути створена в XML досить легко, а не за допомогою редактора макетів:

<android.support.constraint.Guideline
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/guideline"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.5" />

1
Я не міг знайти спосіб, як створити керівництво з обмеженням. Я хочу, щоб горизонтальна настанова була посеред двох поглядів. Уявіть собі більший вигляд із висотою 100dp вгорі та менший з висотою 50dp знизу. Я хочу розмістити орієнтир посеред простору між ними.
headsvk

3
Я не думаю, що ви можете додати обмеження до самого керівництва. Ви можете додати кілька вказівок, а потім обмежити погляди на ці вказівки. Можливо, ви захочете опублікувати нове запитання із деталями того, що ви намагаєтесь досягти. Не соромтесь також вставити його сюди.
AdamK

Дякую, шановний пане. Це була своєчасна та ефективна допомога.
iSofia

Я хочу надати пропорційну ширину переглядам. Наприклад, наприклад, я хочу, щоб кнопка загального користування мала вдвічі ширшу кнопки збереження. Без використання настанов, оскільки мої погляди не розташовані поруч, як у цьому прикладі. Це можливо?
Shubham Naik

Ви повинні конвертувати значення, наведені вказівками, у фактичні поля чи запаси. Вказівки працюють лише в режимі проектування.
Абхінав Саксена

49

Щоб створити 2 подання в одному рядку, однакової ширини, просто потрібно визначитись

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <Button
        android:id="@+id/button1"
        android:layout_width="0dp"  
        android:layout_height="wrap_content"
        android:text="Button 1"
        app:layout_constraintEnd_toStartOf="@+id/button2"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/button1" />

</android.support.constraint.ConstraintLayout>

Примітка

  • ширина = 0dp (MATCH_CONSTRAINT )
  • Обмеження button1і button2повинно подобатися вище

Результат

БІЛЬШЕ
Якщо ви хочете View1більше, ніж View2можете використовувати weightабо percent.
Наприклад, View1ширина = 2 * View2ширина використання ваги

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <Button
        android:id="@+id/button3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 3"
        app:layout_constraintEnd_toStartOf="@+id/button4"
        app:layout_constraintHorizontal_weight="2"
        app:layout_constraintStart_toStartOf="parent"
        />

    <Button
        android:id="@+id/button4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@+id/button3"
        />

</android.support.constraint.ConstraintLayout>

Результат

Наприклад, View1ширина = 2 * View2ширина використання відсотків

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <Button
        android:id="@+id/button5"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 5"
        app:layout_constraintEnd_toStartOf="@+id/button6"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintWidth_percent="0.667"
        />

    <Button
        android:id="@+id/button6"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button 6"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/button5"
        app:layout_constraintWidth_percent="0.333"
        />

</android.support.constraint.ConstraintLayout>

Результат


23

Добре, якщо це комусь допоможе

ключ тут app:layout_constraintHorizontal_weight="1"і
найкраще про обмеження компонування є те , що він підтримує циклічну залежність і ось це те , що я зробив , використовуючи саме це.

Для першої дитини
app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"

Для другої дитини

app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"

ось повна демонстрація

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInputParent"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent">

    <EditText
        android:id="@+id/editTextParent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/state" />
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInputFirstChild"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toStartOf="@+id/textInputSecondChild"
    app:layout_constraintHorizontal_weight="1"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textInputParent">

    <EditText
        android:id="@+id/editTextChildOne"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/pin_code" />
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInputSecondChild"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintHorizontal_weight="1"
    app:layout_constraintLeft_toRightOf="@+id/textInputFirstChild"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/textInputParent">

    <EditText
        android:id="@+id/editTextChildSecond"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/country" />
</android.support.design.widget.TextInputLayout>

9

Ви повинні прочитати про зважених ланцюгах. Приклад коду тут.

<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="wrap_content"
    >

    <TextView
        android:id="@+id/figure_1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintEnd_toStartOf="@id/figure_2"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toStartOf="parent"
        tools:text="1"
        />

    <TextView
        android:id="@+id/figure_2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintEnd_toStartOf="@id/figure_3"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@id/figure_1"
        tools:text="2"
        />

    <TextView
        android:id="@+id/figure_3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintEnd_toStartOf="@id/figure_4"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@id/figure_2"
        tools:text="3"
        />

    <TextView
        android:id="@+id/figure_4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="1"
        app:layout_constraintStart_toEndOf="@id/figure_3"
        tools:text="4"
        />
</android.support.constraint.ConstraintLayout>

Таким чином, встановити android:layout_width="0dp", app:layout_constraintHorizontal_weight="1"і пов'язати кожен вид з сусідами , як:

app:layout_constraintStart_toEndOf="@id/figure_2"
app:layout_constraintEnd_toStartOf="@id/figure_4"

введіть тут опис зображення


в чому сенс розміщення ще однієї відповіді, як і іншої, опублікованої два роки тому?

@Subzero, я багато разів бачив однакові відповіді з високою швидкістю. Навіть рядки коду були однаковими. Я підозрюю, що деякі автори скопіювали з мене і навіть отримали більше плюсів. У цьому випадку відповіді різні, я також використовував інші джерела, щоб зрозуміти, як працюють ваги ConstraintLayout, і лише першої відповіді було недостатньо для отримання зображення вище.
CoolMind

3

Після того як ви маєте свої прикуті предмети, ви все одно можете використовувати ваги на них, як відносне розташування, щоб тримати їх рівномірно розташованими. Наведений нижче приклад показує, як рівномірно розподілити їх за різними розмірами textViews.

<TextView1
     app:layout_constraintHorizontal_weight="1" />
 <TextView2
     app:layout_constraintHorizontal_weight="1" />
 <TextView3
     app:layout_constraintHorizontal_weight="1" />
 <TextView4
     app:layout_constraintHorizontal_weight="1" />

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.