Макеты таблиц можно использовать для отображения табличных данных или аккуратного выравнивания содержимого экрана аналогично таблице HTML на веб-странице. Узнайте, как их создавать с помощью макетов XML-файлов и с помощью кода.
Понимание макетов важно для хорошего дизайна приложений Android. В этом руководстве вы узнаете все о макетах таблиц, которые организуют элементы управления пользовательского интерфейса или виджеты на экране в аккуратно определенных строках и столбцах. При правильном использовании макеты таблиц могут быть мощной парадигмой макетов, при которой приложения Android могут создавать свои экраны или отображать табличные данные.
Что такое макет таблицы?
Макет таблицы — это именно то, что вы могли ожидать: сетка, состоящая из строк и столбцов, где ячейка может отображать элемент управления представлением. С точки зрения дизайна пользовательского интерфейса, TableLayout состоит из элементов управления TableRow — по одному для каждой строки в вашей таблице. Содержимое TableRow — это просто элементы управления представлением, которые будут помещаться в каждую «ячейку» таблицы.
Появление TableLayout регулируется несколькими дополнительными правилами. Во-первых, количество столбцов во всей таблице соответствует количеству столбцов в строке с наибольшим количеством столбцов. Во-вторых, ширина каждого столбца определяется как ширина самого широкого содержимого в столбце. Атрибуты layoutLwidth дочерних строк и ячеек TableLayout всегда являются MATCH_PARENT — хотя они могут быть помещены в файл XML, фактическое значение не может быть переопределено. Можно определить layout_height ячейки TableLayout, но атрибут TableRow для layout_height всегда равен WRAP_CONTENT. Ячейки могут охватывать столбцы, но не строки. Это делается с помощью атрибута layout_span дочернего представления TableRow. Ячейка — это одно дочернее представление в TableRow. Если вы хотите более сложную ячейку с несколькими представлениями, используйте представление макета для инкапсуляции других представлений.
Тем не менее, некоторые правила могут быть изменены. Столбцы могут быть помечены как растягиваемые, что означает, что ширина может увеличиваться до размера родительского контейнера. Столбцы также могут быть помечены как сокращающиеся, что означает, что их можно уменьшить по ширине, чтобы весь ряд поместился в пространство, предоставленное родительским контейнером. Вы также можете свернуть весь столбец.
Для полной документации по макетам таблиц см. Документацию Android SDK для класса TableLayout . Связанные атрибуты XML для использования в ресурсах XML также определены в документации .
Разработка простого макета таблицы
Расположение лучше всего объясняется на примере, а расположение таблиц ничем не отличается. Допустим, мы хотим создать экран, который показывает расширенный прогноз погоды. Расположение таблицы может быть хорошим выбором для организации этой информации:
- В первом TableRow мы можем отобразить заголовок для экрана.
- Во втором TableRow мы можем отображать даты в привычном календарном формате.
- В третьей Таблице строк мы можем отобразить информацию о дневной высокой температуре.
- В четвертой Таблице строк мы можем отобразить информацию о дневной низкой температуре.
- В пятой Таблице строк мы можем отображать графику для определения погодных условий, таких как дождь, снег, солнце или облачность с вероятностью появления фрикадельки.
На этом первом рисунке показан ранний взгляд на таблицу в редакторе макета:
Определение ресурса макета XML с помощью макета таблицы
Наиболее удобный и поддерживаемый способ разработки пользовательских интерфейсов приложений — создание ресурсов макета XML. Этот метод значительно упрощает процесс проектирования пользовательского интерфейса, перенося большую часть статического создания и компоновки элементов управления пользовательского интерфейса и определения атрибутов элемента управления в XML вместо того, чтобы засорять код.
Ресурсы XML-макета должны храниться в иерархии каталогов проекта / res /. Давайте посмотрим на макет таблицы, представленной в предыдущем разделе. Этот файл ресурсов макета, метко названный /res/layout/table.xml, определен в XML следующим образом:
1
|
<?xml version=»1.0″ encoding=»utf-8″?> <TableLayout xmlns:android=»http://schemas.android.com/apk/res/android» android:id=»@+id/tableLayout1″ android:layout_width=»match_parent» android:layout_height=»match_parent» android:shrinkColumns=»*» android:stretchColumns=»*»> <TableRow android:id=»@+id/tableRow4″ android:layout_height=»wrap_content» android:layout_width=»match_parent» android:gravity=»center_horizontal»> <TextView android:id=»@+id/textView9″ android:layout_width=»match_parent» android:layout_height=»wrap_content» android:textStyle=»bold» android:typeface=»serif» android:textSize=»18dp» android:text=»Weather Table» android:gravity=»center» android:layout_span=»6″></TextView> </TableRow> <TableRow android:id=»@+id/tableRow1″ android:layout_height=»wrap_content» android:layout_width=»match_parent»> <TextView android:id=»@+id/TextView04″ android:text=»»></TextView> <TextView android:id=»@+id/TextView04″ android:text=»Feb 7″ android:textStyle=»bold» android:typeface=»serif»></TextV
|
Напомним, что изнутри Activity требуется только одна строка кода в методе onCreate () для загрузки и отображения ресурса макета на экране. Если ресурс макета был сохранен в файле /res/layout/table.xml, эта строка кода будет выглядеть так:
setContentView (R.layout.table);
В этом макете таблицы все столбцы установлены на сжатие и растяжение с использованием «*» в значении. Если только некоторые столбцы должны сжиматься или растягиваться, значения будут разделять запятыми (используя индексы на основе 0 для столбцов).
Теперь таблица выглядит так, как показано на скриншотах в портретном и альбомном режимах.
Определение макета таблицы программно
Вы также можете программно создавать и настраивать макеты таблиц в Java. Это делается с помощью классов TableLayout и TableRow (android.widget.TableLayout и android.widget.TableRow). Вы найдете уникальные параметры отображения для каждого элемента управления в классах TableLayout.LayoutParams и TableRow.LayoutParams. Кроме того, типичные параметры макета (android.view.ViewGroup.LayoutParams), такие как layout_height и layout_width, а также параметры полей (ViewGroup.MarginLayoutParams) все еще применяются к объектам TableLayout и TableRow, но не обязательно к ячейкам таблицы. Для ячеек таблицы (любой View внутри TableRow) ширина всегда равна MATCH_PARENT. Высота может быть определена, но по умолчанию имеет значение WRAP_CONTENT и не требует указания.
Вместо того, чтобы загружать ресурс макета напрямую с помощью метода setContentView (), как показано ранее, если вы создаете макет программно, вы должны вместо этого создать содержимое экрана в Java, а затем предоставить родительский объект макета, который содержит все содержимое элемента управления для отображения в виде дочерние представления к методу setContentView (). В этом случае используемый родительский макет будет создан макет таблицы.
Например, следующий код иллюстрирует, как программно настроить Activity для создания параметров макета TableLayout и воспроизвести пример, показанный ранее в XML:
@Override public void onCreate (BundlevedInstanceState) { super.onCreate (savedInstanceState); TableLayout table = new TableLayout (this); table.setStretchAllColumns (истина); table.setShrinkAllColumns (истина); TableRow rowTitle = new TableRow (это); rowTitle.setGravity (Gravity.CENTER_HORIZONTAL); TableRow rowDayLabels = new TableRow (this); TableRow rowHighs = новый TableRow (это); TableRow rowLows = новый TableRow (это); TableRow rowConditions = new TableRow (this); rowConditions.setGravity (Gravity.CENTER); TextView пустой = новый TextView (это); // заголовок столбца / строки TextView title = new TextView (это); title.setText («Таблица погоды Java»); title.setTextSize (TypedValue.COMPLEX_UNIT_DIP, 18); title.setGravity (Gravity.CENTER); title.setTypeface (Typeface.SERIF, Typeface.BOLD); TableRow.LayoutParams params = new TableRow.LayoutParams (); params.span = 6; rowTitle.addView (title, params); // метка столбца TextView highsLabel = новый TextView (это); highsLabel.setText ("Дневной максимум"); highsLabel.setTypeface (Typeface.DEFAULT_BOLD); TextView lowsLabel = new TextView (это); lowsLabel.setText ("Дневной минимум"); lowsLabel.setTypeface (Typeface.DEFAULT_BOLD); Условия TextViewLabel = новый TextView (это); conditionsLabel.setText ( "Условия"); conditionsLabel.setTypeface (Typeface.DEFAULT_BOLD); rowDayLabels.addView (пусто); rowHighs.addView (highsLabel); rowLows.addView (lowsLabel); rowConditions.addView (conditionsLabel); // столбец дня 1 TextView day1Label = новый TextView (это); day1Label.setText ("7 февраля"); day1Label.setTypeface (Typeface.SERIF, Typeface.BOLD); TextView day1High = новый TextView (это); day1High.setText ( "28 ° F"); day1High.setGravity (Gravity.CENTER_HORIZONTAL); TextView day1Low = новый TextView (это); day1Low.setText ( "15 ° F"); day1Low.setGravity (Gravity.CENTER_HORIZONTAL); ImageView day1Conditions = новый ImageView (это); day1Conditions.setImageResource (R.drawable.hot); rowDayLabels.addView (day1Label); rowHighs.addView (day1High); rowLows.addView (day1Low); rowConditions.addView (day1Conditions); // столбец day2 TextView day2Label = новый TextView (это); day2Label.setText ("8 февраля"); day2Label.setTypeface (Typeface.SERIF, Typeface.BOLD); TextView day2High = новый TextView (это); day2High.setText ( "26 ° F"); day2High.setGravity (Gravity.CENTER_HORIZONTAL); TextView day2Low = новый TextView (это); day2Low.setText ( "от 14 ° F"); day2Low.setGravity (Gravity.CENTER_HORIZONTAL); ImageView day2Conditions = новый ImageView (это); day2Conditions.setImageResource (R.drawable.pt_cloud); rowDayLabels.addView (day2Label); rowHighs.addView (day2High); rowLows.addView (day2Low); rowConditions.addView (day2Conditions); // столбец day3 TextView day3Label = новый TextView (это); day3Label.setText ("9 февраля"); day3Label.setTypeface (Typeface.SERIF, Typeface.BOLD); TextView day3High = новый TextView (это); day3High.setText ( "23 ° F"); day3High.setGravity (Gravity.CENTER_HORIZONTAL); TextView day3Low = новый TextView (это); day3Low.setText ( "3 ° F"); day3Low.setGravity (Gravity.CENTER_HORIZONTAL); ImageView day3Conditions = новый ImageView (это); day3Conditions.setImageResource (R.drawable.snow); rowDayLabels.addView (day3Label); rowHighs.addView (day3High); rowLows.addView (day3Low); rowConditions.addView (day3Conditions); // столбец day4 TextView day4Label = новый TextView (это); day4Label.setText ("10 февраля"); day4Label.setTypeface (Typeface.SERIF, Typeface.BOLD); TextView day4High = новый TextView (это); day4High.setText ( "17 ° F"); day4High.setGravity (Gravity.CENTER_HORIZONTAL); TextView day4Low = новый TextView (это); day4Low.setText ( "5 ° F"); day4Low.setGravity (Gravity.CENTER_HORIZONTAL); ImageView day4Conditions = новый ImageView (это); day4Conditions.setImageResource (R.drawable.lt_snow); rowDayLabels.addView (day4Label); rowHighs.addView (day4High); rowLows.addView (day4Low); rowConditions.addView (day4Conditions); // столбец day5 TextView day5Label = новый TextView (это); day5Label.setText ("11 февраля"); day5Label.setTypeface (Typeface.SERIF, Typeface.BOLD); TextView day5High = новый TextView (это); day5High.setText ( "19 ° F"); day5High.setGravity (Gravity.CENTER_HORIZONTAL); TextView day5Low = новый TextView (это); day5Low.setText ( "6 ° F"); day5Low.setGravity (Gravity.CENTER_HORIZONTAL); ImageView day5Conditions = новый ImageView (это); day5Conditions.setImageResource (R.drawable.pt_sun); rowDayLabels.addView (day5Label); rowHighs.addView (day5High); rowLows.addView (day5Low); rowConditions.addView (day5Conditions); table.addView (rowTitle); table.addView (rowDayLabels); table.addView (rowHighs); table.addView (rowLows); table.addView (rowConditions); setContentView (таблица); }
Давайте внимательнее посмотрим на листинг кода Java выше. Сначала мы создаем элемент управления TableLayout и устанавливаем атрибуты shrinkable и stretchable в true для всех столбцов, используя методы setStretchAllColumns () и setShrinkAllColumns (). Далее мы систематически создаем пять TableRow. Каждый TableRow будет содержать элементы управления представлением (элементы управления TextView для заголовка, даты, максимумы и минимальные данные, а также элементы управления ImageView для графики погодных условий). Вы увидите, как обрабатывается диапазон столбцов с первым TableRow. Конкретные столбцы представлений создаются, стилизуются и добавляются по порядку в соответствующий TableRow с помощью метода addView (). Каждый TableRow добавляется к элементу управления TableLayout по порядку, используя метод addView () класса TableLayout. Наконец, мы загружаем TableLayout и отображаем его на экране с помощью метода setContentView ().
Как видите, размер кода может быстро увеличиваться по мере добавления на экран большего количества элементов управления. Для организации и удобства обслуживания лучше всего определять и использовать макеты программно для нечетного случая, а не для нормы. Кроме того, в таком случае данные обычно поступают из какого-то другого источника, а не из строк, которые мы вводим, поэтому цикл может быть более подходящим для многих приложений.
Результаты показаны на следующем рисунке. Как видите, они такие же, как и предыдущие результаты — как и ожидалось.
Концерны TableLayout
Хотя макеты таблиц могут использоваться для разработки целых пользовательских интерфейсов, они обычно не являются лучшим инструментом для этого, поскольку они получены из LinearLayout и не являются наиболее эффективными элементами управления макетом. Если вы подумаете об этом, TableLayout — это чуть больше, чем организованный набор вложенных LinearLayouts, а слишком глубокие вложения макетов обычно не рекомендуется из-за проблем с производительностью. Однако для данных, которые уже имеют формат, подходящий для таблицы, такой как данные электронной таблицы, может быть разумным выбором макет таблицы.
Кроме того, данные макета таблицы могут различаться в зависимости от размеров экрана и разрешений. Как правило, рекомендуется использовать прокрутку при отображении больших объемов данных. Например, если в примере погоды, использованном ранее, также содержалась «запись» условий, этот текст мог бы состоять из одного предложения или двадцати предложений, поэтому было бы целесообразно включить вертикальную и / или горизонтальную прокрутку.
Вывод
Пользовательские интерфейсы приложений Android определяются с помощью макетов, а макеты таблиц невероятно удобны для отображения данных представления или элементов управления в строках и столбцах. Использование макетов таблиц там, где они уместны, может упростить и ускорить многие конструкции экрана. Однако имейте в виду, что TableLayout является производным от LinearLayout и имеет много одинаковых ограничений производительности.
Об авторах
Разработчики мобильных приложений Лорен Дарси и Шейн Кондер являются соавторами нескольких книг по разработке Android: углубленная книга по программированию под названием « Разработка беспроводных приложений для Android» и « Разработка Android-приложений Sams TeachYourself за 24 часа» . Когда они не пишут, они тратят свое время на разработку мобильного программного обеспечения в своей компании и оказание консультационных услуг. С ними можно связаться по электронной почте [email protected] , через их блог на androidbook.blogspot.com и в Twitter @androidwireless .