Програмне створення ConstraintLayout і позиціонування

Для створення контейнера в коді Java застосовується однойменний клас ConstraintLayout, для створення об'єкта якого в конструктор передають значення для ширини і висоти елемента:

ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams
                (ConstraintLayout.LayoutParams.WRAP_CONTENT , ConstraintLayout.LayoutParams.WRAP_CONTENT);

Перший параметр встановлює ширину елемента, а другий - висоту. ConstraintLayout.LayoutParams.WRAP_CONTENT вказує, що елемент матиме ті розміри, які необхідні для того, щоб вивести на екран його вміст. Крім ConstraintLayout.LayoutParams.WRAP_CONTENT можна застосовувати константу ConstraintLayout.LayoutParams.MATCH_CONSTRAINT, яка аналогічна застосуванню значення "0dp" в атрибутах layout_width та layout_height та яка розтягує елемент за шириною або висотою контейнера.

Також можна використовувати точні розміри, наприклад:

ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams
                (ConstraintLayout.LayoutParams.MATCH_CONSTRAINT, 200);

Для налаштування позиціонування всередині ConstraintLayout застосовується клас ConstraintLayout.LayoutParams. Він має досить багато функціоналу. Розглянемо в цьому випадку тільки ті поля, які дають змогу встановити розташування елемента:

  • baselineToBaseline: вирівнює базову лінію елемента по базовій лінії іншого елемента, id якого присвоюється властивості.
  • bottomToBottom: вирівнює нижню межу елемента по нижній межі іншого елемента.
  • bottomToTop: вирівнює нижню межу елемента по верхній межі іншого елемента.
  • leftToLeft: вирівнює ліву межу елемента по лівій межі іншого елемента.
  • leftToRight: вирівнює ліву межу елемента по правій межі іншого елемента.
  • rightToLeft: вирівнює праву межу елемента по лівій межі іншого елемента.
  • rightToRight: вирівнює праву межу елемента по правій межі іншого елемента.
  • startToEnd: вирівнює початок елемента по завершенню іншого елемента.
  • startToStart: вирівнює початок елемента по початку іншого елемента.
  • topToBottom: вирівнює верхню межу елемента по нижній межі іншого елемента.
  • topToTop: вирівнює верхню межу елемента по верхній межі іншого елемента.
  • endToEnd: вирівнює заврішення елемента по завершенню іншого елемента.
  • endToStart: вирівнює завершення елемента по початку іншого елемента.

Як значення ці поля приймають id (ідентифікатор) елемента, щодо якого виконується позиціонування. Якщо розташування встановлюється щодо контейнера ConstraintLayout, то застосовується константа ConstraintLayout.LayoutParams.PARENT_ID.

Розглянемо найпростіший приклад:

package com.example.viewapp;
 
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.os.Bundle;
import android.widget.TextView;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
 
        ConstraintLayout constraintLayout = new ConstraintLayout(this);
        TextView textView = new TextView(this);
        // установка текста текстового поля
        textView.setText("Hello Android");
        // установка размера текста
        textView.setTextSize(30);
 
        ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams
                (ConstraintLayout.LayoutParams.WRAP_CONTENT , ConstraintLayout.LayoutParams.WRAP_CONTENT);
        // позиционирование в левом верхнем углу контейнера
        // эквивалент app:layout_constraintLeft_toLeftOf="parent"
        layoutParams.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID;
        // эквивалент app:layout_constraintTop_toTopOf="parent"
        layoutParams.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
        // устанавливаем размеры
        textView.setLayoutParams(layoutParams);
        // добавляем TextView в ConstraintLayout
        constraintLayout.addView(textView);
 
        setContentView(constraintLayout);
    }
}

У цьому разі значення ConstraintLayout.LayoutParams.WRAP_CONTENT для ширини та висоти вказує, що елемент матиме ті розміри, які необхідні для того, щоб вивести на екран його вміст.

Далі вирівнюємо ліву межу елемента по лівій стороні контейнера:

layoutParams.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID;

Ця установка аналогічна використанню атрибута app:layout_constraintLeft_toLeftOf="parent".

Потім вирівнюємо верхню межу елемента по верхній стороні контейнера:

layoutParams.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;

Ця установка аналогічна використанню атрибута app:layout_constraintTop_toTopOf="parent".

І наприкінці застосовуємо об'єкт ConstraintLayout.LayoutParams до TextView:

constraintLayout.addView(textView);

У підсумку елемент TextView буде розташований у верхньому лівому кутку ConstraintLayout:

Розглянемо інший приклад - встановлення розташування елементів відносно один одного:

package com.example.viewapp;
 
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
 
        ConstraintLayout constraintLayout = new ConstraintLayout(this);
 
        EditText editText = new EditText(this);
        editText.setHint("Введите Email");
        editText.setId(View.generateViewId());
         
        Button button = new Button(this);
        button.setText("Отправить");
        button.setId(View.generateViewId());
 
        ConstraintLayout.LayoutParams editTextLayout = new ConstraintLayout.LayoutParams
                (ConstraintLayout.LayoutParams.WRAP_CONTENT , ConstraintLayout.LayoutParams.WRAP_CONTENT);
        editTextLayout.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID;
        editTextLayout.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
        editTextLayout.rightToLeft = button.getId();
        editText.setLayoutParams(editTextLayout);
        constraintLayout.addView(editText);
 
        ConstraintLayout.LayoutParams buttonLayout = new ConstraintLayout.LayoutParams
                (ConstraintLayout.LayoutParams.WRAP_CONTENT , ConstraintLayout.LayoutParams.WRAP_CONTENT);
        buttonLayout.leftToRight = editText.getId();
        buttonLayout.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
        button.setLayoutParams(buttonLayout);
        constraintLayout.addView(button);
 
        setContentView(constraintLayout);
    }
}

При розташуванні одного елемента відносно іншого, нам потрібно знати id вторрого елемента. Якщо елемент визначено в коді Java, то спочатку треба згенерувати ідентифікатор:

editText.setId(View.generateViewId());
button.setId(View.generateViewId());

Потім можна застосовувати ідентифікатори елементів для встановлення позиціонування позиціонування. Так, права межа EditText вирівнюється по лівій межі кнопки:

editTextLayout.rightToLeft = button.getId();

А ліва межа кнопки вирівнюється по правій межі елемента EditText:

buttonLayout.leftToRight = editText.getId();