Страницы

Поиск по вопросам

среда, 25 декабря 2019 г.

Создать идентичные 9х9 элементов TextView в виде таблички - с равными размерами

#android #android_textview #android_linearlayout #height #width


У меня есть компоновка 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).




Сожалею, что нереально тяжело въехать, в чём же у меня заключается проблема, но я
постарался максимально подробно и корректно описать её :).
    


Ответы

Ответ 1



Для того, чтобы сделать ячейки масшатбируемыми и квадратными, можно использовать свойство соотношения сторон 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); Не правда ли удобно?

Комментариев нет:

Отправить комментарий