У меня есть компоновка LinearLayout вертикальной ориентации, в которой находятся 9 компоновок LinearLayout горизонтальной ориентации, в каждой из которых по 9 TextView (итого 9 * 9 = 81 элемент TextView). Для грамотной реализации этого творчества я создаю по 9 горизонтальных компоновок LinearLayout и по 9 TextView в каждой из них в Java-коде, а затем, соответственно, добавляю их в основную компоновку компонента Activity примерно так:
for (int y = 8; y >= 0; y--) {
LinearLayout mLinearLayout_row = ...//компоновка горизонтальной ориентации
for (x = 0; x < 9; x++) {
TextView mTextView = layoutInflater.inflate(R.layout.mtextview, ...
mLinearLayout_row.addView(mMTextView);
}
myMainActivityLayout.addView(mLinearLayout_row, 0);
}
Все компоновки имеют длину MATCH_PARENT, а высоту WRAP_CONTENT. Вот код mtextview.xml
На экране ширИны всех элементов TextView выглядят равными (если не вглядываться). Но на самом деле система Android задаёт ширину нескольким последним элементам с правой стороны во всех рядах чуть меньшую ширину - это система вычисляет алгоритмом за счёт известного значения атрибута layout_weight у всех TextView
Теперь перейду к проблеме. У меня не получается сделать элементы TextView квадратными, таблица выглядит приплюснутой.
Я пробовал следующие способы:
Использовать кастомный TextView, в классе которого переопределив метод onMeasure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
Метод очень плох, так как элементы то делаются квадратными, но слева они большие, а справа маленькие - это очень некрасиво выглядит.
Использовать кастомную основную компоновку LinearLayout, в классе которой переопределив метод onMeasure (так же, как в п.1) и установив значение атрибута layout_height у TextView на match_parent - вообще никаких изменений.
В коде компонента Activity, в которой всё это происходит, переопределить метод onResume, в котором пытаться получить ширину всех TextView и задать им высоту, равную известной ширине... в общем-то способ не профессиональный и не оптимальный, по моему мнению, но, несмотря на это, я попробовал использовать этот способ, а оказалось, что, когда вызывается метод onResume система ещё не знает ширину элементов!!! (значение функции mTextView.getWidth(), полученное в этом методе равно 0).
Сожалею, что нереально тяжело въехать, в чём же у меня заключается проблема, но я постарался максимально подробно и корректно описать её :).
Ответ
Для того, чтобы сделать ячейки масшатбируемыми и квадратными, можно использовать свойство соотношения сторон app:layout_constraintDimensionRatio в ConstraintLayout
Это позволит вам сделать ячейки квадратными, вне зависимости от расширения экрана, т.к. они просто ужмутся по высоте и ширине
Но я предлагаю пойти вам дальше и переверстать экран с помощью recyclerView (как предложил Виталий в комментариях). Во-первых, это избавит вас от проблемы адресации к этим ячейкам, ведь их нужно будет заполнять и считывать. А во-вторых, реализация с RecycelerView будет эстетичнее (в разметке RecyclerView + адаптер + ViewHolder - вы сами убедитесь в простоте такой реализации). Установив размер 1 в item RecyclerView, вы автоматически его установите всем ячейкам.
Адаптер для RecyclerView стандартный, но нужно переопределить LayouManager. Создаете LayoutManager, наследуете его от GridLayoutManager (можно внутри адаптера):
private static class NonScrollableGridLayoutManager extends GridLayoutManager {
NonScrollableGridLayoutManager(Context context, int span) {
super(context, span);
}
@Override
public boolean canScrollVertically() {
return false;
}
@Override
public boolean canScrollHorizontally() {
return false;
}
}
В адаптере создаете метод, возвращающий объект LayoutManager
public static RecyclerView.LayoutManager getLayoutManager(Context context) {
return new NonScrollableGridLayoutManager(context, COUNT_OF_ITEM_IN_LINE);
}
Затем устанавливаете для RecyclerView ваш LayoutManager
binding.monthContent.setLayoutManager(CalendarAdapter.getLayoutManager(
binding.getRoot().getContext()));
binding.monthContent.setAdapter(daysAdapter);
binding.monthContent.setItemAnimator(null);
Не правда ли удобно?
Комментариев нет:
Отправить комментарий