#android #android-gridlayout #android-imagebutton #android-shape
Вопрос:
Вот чего я хочу:
У меня есть GridLayout
внутри a ConstraintLayout
, к которому я динамически добавляю несколько строк и столбцов custom ImageButtons
( BoardCells
). Кнопки изображений отображают круги, используя shape
XML-файл (код ниже).
Я хочу, чтобы ячейки доски имели одинаковую ширину и высоту, чтобы форма действительно была кругом, а не овалом. Я также хочу, чтобы настольные ячейки занимали как можно больше места на экране и распределялись равномерно.
Вот что я попробовал:
Я попробовал установить фиксированный размер (в dp) для ячеек платы и установить значение layout_width для сетки wrap_content
, но это будет работать только на разных экранах, которые довольно похожи и не используют оптимальное пространство. Снимок экрана сетки с ячейками доски фиксированного размера.
Когда я не задаю размер для фигуры и ячейки доски, тогда вообще ничего не отображается , не имеет значения, есть ли у GridLayout match_parent
wrap_content
или 0dp
.
Поэтому я попытался придать всем доскам одинаковый вес внутри сетки, как это:
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f);
params.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f);
this.setLayoutParams(params);
this.setScaleType(ScaleType.CENTER);
Но установка column-
и rowSpec
не сохраняет соотношение, поэтому я не получаю кругов (что имеет смысл).
Снимок экрана сетки с параметрами столбцов и строк, равными 1 для каждой ячейки платы.
Поэтому я попытался установить только columnSpec и установить ScaleType
CENTER
значение «или CENTER_INSIDE
«, надеясь, что это сохранит соотношение, но растянется как можно больше. Но это растягивается только по горизонтали и принимает фиксированный размер по вертикали. Снимок экрана сетки с параметром columnSpec, равным 1, и ЦЕНТРОМ масштабирования
Затем я подумал, что я бы реализовал onLayoutChangedListener
для GridLayout, но пытался добавить дочерние элементы в GridLayout внутри набора onLayoutChanged
результатов в «неправильно вызванных ошибках requestLayout ()» в моем журнале.
Моя последняя идея состоит в том, чтобы сначала отобразить пустую сетку, и только когда пользователь нажимает кнопку, чтобы начать игру (кнопка все равно существует, потому что вы можете играть в несколько раундов), и представление уже раздуто и отображается, я получаю ширину и высоту сетки и вычисляю максимально возможный размер ячеек доски. Но этот подход, по-видимому, не является лучшей практикой.
Теперь я не знаю, что было бы правильно сделать. Я сделал что-то не так или есть какое-то решение, о котором я вообще не думал? Должен ли я экспериментировать с кучей эмулируемых устройств и создавать XML-файлы формы для разных размеров экрана? Подходит ли динамический подход?
Вот соответствующий код:
Файл 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"
android:background="@color/wood"
android:padding="10dp"
tools:context=".MainActivity">
<androidx.gridlayout.widget.GridLayout
android:id="@ id/board_cells"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@ id/guideline70"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/guideline8"
android:layout_margin="10dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I fill this GridLayout with custom ImageButtons with the following Code:
gridLayoutBoard.setUseDefaultMargins(true);
gridLayoutBoard.setRowCount(10);
gridLayoutBoard.setColumnCount(6);
for (int i = gridLayoutBoard.getRowCount()-1; i >= 0; i--) {
for (int j = 0; j < gridLayoutBoard.getColumnCount(); j ) {
if (j == 0 || j == 5) {
Indikator text= new TextView;
gridLayoutBoard.addView(text);
} else {
BoardCell boardCell = new BoardCell(this);
gridLayoutBoard.addView(boardCell);
}
}
}
The ImageButtons (BoardCells) set their background to this selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<layer-list>
<item android:drawable="@drawable/cell_solid"/>
<item android:drawable="@drawable/cell_gradient"/>
</layer-list>
</item>
</selector>
which uses the following solid shape and a gradient with the same size and shape:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/grey_cell_dings" />
<size
android:width="30dp"
android:height="30dp"/>
</shape>