Android gridview vs gridlayout

GridView

Знакомьтесь — GridView

Компонент GridView представляет собой плоскую таблицу. Для GridView можно использовать собственные поля для отображения элементов данных, создав класс, производный от класса ArrayAdapter или BaseAdapter и т.п, и переопределив его метод getView().

В старых версиях студии находился в разделе Containers, сейчас находится в Legacy и считается устаревшим.

Число столбцов для GridView чаще задаётся статически. Число строк в элементе определяется динамически на основании числа элементов, которые предоставляет адаптер.

Свойства

  • android:numColumns — определяет количество столбцов. Если поставлено значение auto_fit, то система вычислит количество столбцов, основанное на доступном пространстве
  • android:verticalSpacing — устанавливает размер пустого пространства между ячейками таблицы
  • android:columnWidth — устанавливает ширину столбцов
  • android:stretchMode — указывает, куда распределяется остаток свободного пространства для таблицы с установленным значением android:numColumns=»auto_fit». Принимает значения columnWidth для paспределения остатка свободного пространства между ячейками столбцов для их увеличения или spacingWidth — для увеличения пространства между ячейками

Базовый пример

Если поместить GridView на форму, то увидим следующую картину.

Внесём небольшие правки

В коде реализуем наполнение таблицы через адаптер. Создадим новый файл DataAdapter.java:

Теперь напишем код для основного окна приложения. Как и у ListView, нам нужно использовать метод setAdapter(), а также методы setOnItemSelectedListener(), onItemSelected(), onNothingSelected().

Запустите проект и начинайте выбирать любой элемент — его название отобразится в текстовой метке в верхней части экрана. Я обратил внимание, что в эмуляторе с помощью джойстика можно выбрать нужный элемент, но в современных телефонах джойстика нет, поэтому я позже добавил метод setOnItemClickListener(), чтобы можно было щёлкать по элементам в GridView и выводить их названия в метке.

GridView с картинками

Вместо текста можно использовать и картинки. Немного модифицируем проект. В шаблоне разметки изменим GridView:

Создадим новый адаптер ImageAdapter.java, в котором будет возможность подключать картинки

Теперь код в основной активности:

Зная номер позиции можно доработать программу, чтобы при щелчке на картинке, она открывалась на весь экран. Давайте так и сделаем. Создадим новый XML-файл разметки в папке res/layout под именем full_image.xml:

Создадим новую активность, в которой будет выводиться изображение на весь экран (файл FullImageActivity.java):

Класс получает от намерения номер позиции и выводит по этому номеру изображение из ресурсов.

Теперь в основной активности модифицируем код для щелчка

Осталось добавить в манифест новую активность:

У нас получилась галерея с просмотром отдельной картинки.

GridView с картинками и пояснительным текстом

Модифицируем предыдущий пример и создадим сетку, состоящую из картинок с сопроводительным текстом внизу.

Можно было оставить предыдущую разметку для активности, но я решил чуть её изменить, убрав лишние элементы

Теперь создадим разметку для отдельной ячейки сетки — нам нужны ImageView и TextView:

res/layout/cellgrid.xml

Создадим новый класс ImageTextAdapter. Он практически не отличается от класса ImageAdapter, поменялся только метод getView(), разницу в коде я закоментировал для сравнения

Осталось вызвать нужный адаптер в активности:

Убрать вертикальную прокрутку

Прочитал заметку про убирание вертикальной прокрутки, которая возникает при движении пальцем вверх. Может пригодится кому-то:

Галерея

Рассмотрим вариант создания галереи на основе GridView.

Создаём новый проект. Также нужно подготовить фотографии для галереи, которые следует поместить в папку res/drawable-hdpi.

Поместим на главном экране приложения GridView:

Создадим новый класс ImageAdapter.java, наследующий от BaseAdapter, для размещения изображений в сетке GridView через собственный адаптер.

Читайте также:  Хороший переводчик для android

Открываем основной класс приложения и связываем через созданный адаптер изображения с GridView:

Запустим проект и проверим, что всё отображается нормально.

Не обращайте внимания, что картинки на скриншоте повторяются, просто было лень готовить пятнадцать разных фотографий.

На этом урок можно было закончить, но давайте доработаем приложение, чтобы выбранная картинка отображалась в полном размере на весь экран. Для этого нужно передать идентификатор выбранного изображения новой активности.

Создадим в папке layout файл разметки full_image.xml для этой цели.

Создадим новый класс FullImageActivity.java для активности, которая будет отображать картинку на весь экран. Активность через намерение будет получать идентификатор картинки и выводить её на экран.

Не забываем прописать новый класс в манифесте проекта.

Возвращаемся к главной активности и добавляем обработчик щелчков на сетке:

Снова запускаем проект и щёлкаем по любой миниатюре — должен запуститься новый экран с картинкой во весь рост. Теперь можно разглядеть кота получше.

Загружаем картинки из внешнего накопителя

Попробуем загрузить картинки с внешнего накопителя в GridView. Пример писался под Android 2.3, возможно сейчас уже не заработает.

Разметка основного экрана состоит из одного компонента GridView:

Для данного компонента нужен адаптер. Создадим новый класс ImageAdapter.

ImageAdapter.java

Код для главной активности:

В этом примере при щелчке выводится всплывающее сообщение. Вы можете запустить новую активность с показом выбранной картинки.

Источник

GridLayout (а не GridView), как равномерно распределить всех детей

Я хочу иметь сетку 2×2 с кнопками внутри. Это только ICS, поэтому я пытаюсь использовать новый GridLayout.

Вот XML моего макета:

Проблема в том, что мои взгляды не растягиваются равномерно для каждой строки. Это вызывает много лишнего пространства справа от моего GridLayout.

Я попытался установить layout_gravity=»fill_horizontal» но это применимо только к последнему виду в строке. Это означает, что Cell 1 растягивается полностью, чтобы дать достаточно места для Cell 0.

Мысли о том, как справиться с этим?

UPDATE : весы поддерживаются по API 21. См. Ответ PaulT для получения более подробной информации. END UPDATE Существуют ограничения при использовании GridLayout, следующая цитата взята из документации .

«GridLayout не поддерживает принцип веса, определенный по весу. В общем случае невозможно настроить GridLayout для распределения избыточного пространства в нетривиальных пропорциях между несколькими строками или столбцами … Для полного контроля над Избыточное распределение пространства в строке или столбце, используйте подкласс LinearLayout для хранения компонентов в связанной группе ячеек. «

Вот небольшой пример, который использует подходы LinearLayout. (Я использовал Space Views, который занимает неиспользованную область и нажимает кнопки в нужную позицию.)

Начиная с API 21 понятие веса было добавлено в GridLayout. Для поддержки старых устройств Android вы можете использовать GridLayout из библиотеки поддержки v7.

Следующий XML дает пример того, как вы можете использовать весы для заполнения ширины экрана.

Appcompat21 GridLayout имеет весы столбцов и строк, которые можно использовать, как показано ниже, для равномерного создания каждого элемента сетки в gridlayout, как показано выше.

Вы можете установить ширину каждого ребенка динамически:

Начиная с API 21 без библиотеки поддержки v7 с помощью ScrollView:

Попробуйте добавить в спецификацию GridLayout следующее. Это должно сработать.

андроид: useDefaultMargins = «истина»

Наконец я нашел решение. Как сказал Ротеммиз, вы должны сделать это динамично после этого. Этот код растягивает кнопки, чтобы заполнить представление по горизонтали, но то же самое можно сделать и по вертикали.

(20 для внутренних и внешних отступов и полей. Это можно сделать более универсально, но это намного чище)

Читайте также:  Генератор звуковой частоты для андроида

Тогда его можно вызвать так:

Это должно быть сделано с наблюдателем, потому что нам нужно дождаться, пока изображение будет нарисовано, прежде чем мы будем называть представления.

В моем случае я динамически добавлял кнопки, поэтому для моего решения требовалась часть XML и часть Java. Мне приходилось находить и смешивать решения из нескольких разных мест и думать, что я поделюсь им здесь, чтобы кто-то другой, ищущий подобное решение, мог бы найти его полезным.

Первая часть моего файла макета XML …

grid:useDefaultMargins=»true» не требуется, но я добавил, потому что это выглядело лучше для меня, вы можете применять другие визуальные эффекты (например, отступы), как упомянуто в некоторых ответах здесь. Теперь для кнопок, поскольку я должен добавить их динамически. Вот часть Java моего кода для создания этих кнопок, я включаю только те строки, которые связаны с этим контекстом. Предположим, что мне нужно сделать кнопки из числа myOptions , доступных для моего кода, и я также не копирую код OnClickListener.

Поскольку мы используем GridLayout из библиотеки поддержки, а не стандартный GridLayout, мы должны рассказать о том, что в файле YourProject.grade .

Вы можете сделать это быстрее, переопределив метод ViewGroup onLayout. Это мое универсальное решение:

EDIT: не забывайте match_parent для детей!

Лучшее решение, которое я смог найти, – использовать линейную компоновку (горизонтальную) для каждой строки, в которой вы хотите, и внутри нее назначить ширину кнопки (ячейки) до 0dp, а вес – 1. Для каждого из линейных макетов (строк) назначить высоту До 0dp и весом до 1. Найдите код ниже – также android: layout_gravity = «center_vertical» используется для выравнивания кнопок в строке, если они содержат текст переменной длины. Использование 0dp и вес это довольно аккуратный, но не очень известный трюк.

Это правильный ответ

Я хотел бы иметь центрированную таблицу с выравниваемыми метками и выравниванием значений. Дополнительное пространство должно быть вокруг стола. После много экспериментов и не следуя тому, что документация сказала, что я должен делать, я придумал что-то, что работает. Вот что я сделал:

Это похоже на работу, но GridLayout показывает сообщение:

«Этот макет GridLayout или его родитель LinearLayout бесполезен»

Не уверен, почему это «бесполезно», когда оно работает для меня.

Я не уверен, почему это работает, или если это хорошая идея, но если вы попробуете его и можете предложить лучшую идею, небольшое улучшение или объяснить, почему он работает (или не будет работать), я буду благодарен за отзывы.

Старый вопрос, но хотел добавить мое решение. Я создал «линейную схему сетки», которая имитирует сетку, но использует вложенные линейные макеты. Это позволяет растягиваться, чтобы заполнить пространство.

Вот что я сделал, и я рад сказать, что это сработало для меня. Мне тоже нужна сетка из 2×2, 3×3 и т. Д., Чтобы покрыть весь экран. Gridlayouts не придерживаются ширины экрана. LinearLayouts – вид работы, но вы не можете использовать вложенные веса.

Лучшим вариантом для меня было использование Фрагментов. Я использовал этот учебник, чтобы начать с того, что я хотел сделать.

Activity_main_6 XML (раздувает 3 фрагмента)

Макет базового фрагмента

Класс фрагмента (обрабатывает только инициализацию пользовательского представления) раздувает 2 фрагмента на фрагмент

Это странная работа по использованию вложенных весов. Это дает мне идеальную сетку 2×3, которая заполняет весь экран как моего 10-дюймового планшета, так и моей ДНК-дроида-HTC. Дайте мне знать, как это происходит для вас!

Источник

Полный список

GridView – еще один из компонентов, использующих адаптеры. Он выводит элементы в виде сетки/матрицы/таблицы, нужное подчеркнуть )

Читайте также:  Android tv модели телевизоров

Сделаем простой пример. И рассмотрим интересные атрибуты этого компонента.

Project name: P0571_GridView
Build Target: Android 2.3.3
Application name: GridView
Package name: ru.startandroid.develop.p0571gridview
Create Activity: MainActivity

В экран main.xml поместим GridView:

Создадим в любой папке res/drawable-* файл rect.xml

Это просто прямоугольник, залитый синим цветом. Я буду использовать его как фон. Я эту тему еще не рассматривал в уроках, тут можно почитать подробнее .

Создадим свой layout для адаптера – item.xml

LinearLayout с фоном drawable/rect, который мы создали ранее. И TextView.

Кода немного. Определяем GridView и создаем адаптер. В качестве layout для адаптера используем созданный item.xml, а tvText – это элемент, в который адаптер будет вставлять текст. Метод adjustGridView пока пустой, в нем будем кодить настройки Grid-а.

Давайте смотреть, какие для GridView есть атрибуты.

numColumns и columnWidth

numColumns – кол-во столбцов в сетке. Если его не задавать, то столбец будет по умолчанию один. Запустим приложение и убедимся.

Давайте поменяем это свойство — укажем, например 3. Сделаем это в пустом пока что методе adjustGridView

Сохраним и запустим.

Все верно, получилось три столбца.

Это свойство также может иметь значение AUTO_FIT. В этом случае проверяется значение поля атрибута columnWidth (ширина столбца).

— если ширина столбца явно указана, то кол-во столбцов рассчитывается исходя из ширины, доступной GridView, и ширины столбцов.

— иначе, кол-во столбцов считается равным 2

Проверим. Укажем кол-во столбцов = AUTO_FIT, а ширину столбцов задавать пока не будем.

Запускаем, видим два столбца

Теперь укажем явно ширину столбцов, пусть будет 50.

Теперь кол-во столбцов рассчитывается исходя из их ширины.

Видно, что в экран влезло 6 столбцов. Вы можете поизменять параметр ширины столбцов и убедиться, что их кол-во будет меняться.

horizontalSpacing, verticalSpacing

Это горизонтальный и вертикальный отступы между ячейками. Пусть будет 5.

Между ячейками появилось расстояние.

stretchMode

Этот параметр определяет, как будет использовано свободное пространство, если оно есть. Используется в случае, когда вы указываете ширину столбца и кол-во ставите в режим AUTO_FIT. Изменим наш метод, добавим туда настройку stretch-параметра.

stretchMode может принимать 4 значения:

NO_STRETCH – свободное пространство не используется

Столбцы выровнены по левому краю. Все свободное пространство справа.

STRETCH_COLUMN_WIDTH – свободное пространство используется столбцами, это режим по умолчанию

Столбцы растянуты по ширине. Она уже может не соответствовать той, что указана в setColumnWidth.

STRETCH_SPACING – свободное пространство равномерно распределяется между столбцами

Ширина столбцов неизменна. Увеличены интервалы между ними.

STRETCH_SPACING_UNIFORM – свободное пространство равномерно распределяется не только между столбцами, но и справа и слева

Ширина столбцов неизменна. Увеличены интервалы между ними и с боков.

Разумеется, все эти параметры можно задавать не только программно, но и через атрибуты в layout-файлах. Вместо ArrayAdapter можно использовать любой другой. Можно прикрутить обработчик setOnItemClickListener и получать позицию или id нажатого элемента. Все как в обычных списках.

Есть также хороший гугловский пример по этой теме:

На следующем уроке:

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Оцените статью