Адаптер android studio это

Адаптеры

В Android часто используются адаптеры. Если говорить в общих чертах, то адаптеры упрощают связывание данных с элементом управления. Адаптеры используются при работе с виджетами, которые дополняют android.widget.AdapterView: ListView, ExpandableListView, GridView, Spinner, Gallery, а также в активности ListActivity и др. Сам AdapterView дополняет android.widget.ViewGroup.

Итак, у нас есть набор объектов и есть компонент View. Назначение адаптера заключается в том, чтобы предоставлять дочерние виды для контейнера. Адаптер берет данные и метаданные определенного контейнера и строит каждый дочерний вид. Например, мы формируем пункты списка (массив строк) и передаём его списку ListView.

Вы что-нибудь поняли? Мой кот тоже ничего не понял. Попробуем объяснить по-другому. Что такое вообще адаптер? Это переходник между двумя какими-то предметами. Допустим, между питьевой водой и котом требуется адаптер в виде крана.

В данном случае адаптер спроектирован плохо, приходится изворачиваться.

Однако вернёмся к Android. В приложениях очень часто используется список на основе ListView. Сам список состоит из множества элементов TextView, которые идут друг за другом. Но их количество будет зависеть от того, чтобы мы хотим отобразить. Если нам нужны дни недели, то достаточно семи элементов, если месяцы, то уже двенадцать, ну а если нам нужны имена котов в Кот д’Ивуаре, то счёт пойдет на сотни. Короче говоря, нам нужно составить данные, например, в виде массива и скормить его списку. Адаптер этим и занимается. Он берёт по порядку предоставленные данные и размещает их в списке по порядку. При этом адаптер на лету создаёт нужные компоненты TextView и помещает в него приготовленный текст. Данные могут быть находиться не только в массиве, но и в базе данных. Для такого случая используется другой адаптер. А также вы можете придумать свой адаптер. Существуют уже готовые адаптеры на самые распространённые случаи и их предназначение можно определить по именам. Например, ArrayAdapter использует массив, а CursorAdapter работает с объектом Cursor, используемый в базах данных.

Готовые адаптеры

Все адаптеры, содержащиеся в Android, дополняют базовый адаптер BaseAdapter. Вот список готовых адаптеров:

  • ArrayAdapter — предназначен для работы с ListView. Данные представлены в виде массива, которые размещаются в отдельных элементах TextView
  • ListAdapter — адаптер между ListView и данными. Строго говоря, это класс-интерфейс, который можно использовать и в ArrayAdapter и в SimpleAdapter и т.д.
  • SpinnerAdapter — адаптер для связки данных с элементом Spinner. Это тоже интерфейс, как ListAdapter и работает по схожему принципу
  • SimpleAdapter — адаптер, позволяющий заполнить данными список более сложной структуры, например, два текста в одной строке списка.
  • SimpleCursorAdapter — дополняет ResourceCursorAdapter и создаёт компоненты TextView/ImageView из столбцов, содержащихся в курсоре. Компоненты определяются в ресурсах
  • CursorAdapter — предназначен для работы с ListView, предоставляет данные для списка через курсор, который должен иметь колонку с именем «_id»
  • ResourceCursorAdapter — этот адаптер дополняет CursorAdapter и может создавать виды из ресурсов
  • HeaderViewListAdapter — расширенный вариант ListAdapter, когда ListView имеет заголовки.
  • WrapperListAdapter — еще один адаптер для списков.

BaseAdapter

Стандартные адаптеры не всегда покрывают потребности программиста. Если вам нужен свой собственный адаптер, то в Android есть абстрактный класс BaseAdapter, который можно расширить. Собственный адаптер необходим в тех случаях, когда требуется специальное управление данными или дополнительный контроль над отображением дочерних представлений. Кроме того, вы можете предусмотреть в своём адаптере элементы кэширования для повышения производительности работы.

Пример использования адаптере на основе BaseAdapter можно увидеть при создании GridView с картинками и в других примерах.

У BaseAdapter есть несколько методов, которые следует переопределить. Например, метод getCount() позволяет узнать количество выводимых объектов.

Читайте также:  The android app has launched

Другой важный метод адаптера — getView(), который отвечает за создание отдельных элементов списка. Он вызывается для каждого элемента списка, чтобы определить, какие данные нужно отобразить. Метод getVew() содержит параметр convertView, который позволяет использовать заново уже существующий элемент списка, который не отображается, т.к. пользователь пролистнул его с видимой части дисплея. Если convertView не пустой, он может быть использован заново, чтобы не грузить разметку списка. Подобный подход способствует увеличению производительности.

Метод getView() возвращает View, который фактически является контейнером ViewGroup и содержит в себе другие компоненты, например, ImageView или TextView.

На сайте представлены (будут представлены) практически все примеры с адаптерами. Оставайтесь на связи!

Источник

ArrayAdapter

Создание адаптера

ArrayAdapter является простейшим адаптером, который специально предназначен для работы с элементами списка типа ListView, Spinner, GridView и им подобным. Создать адаптер этого вида можно так:

В параметрах используется контекст, XML-разметка для отдельного элемента списка и массив данных. Контекстом может быть сама активность (this), под разметкой подразумевается компонент, в котором выводится текст, например, TextView, а данными является подготовленный массив, все элементы которого по очереди вставляются в указанную разметку.

Разметку можно создать самостоятельно, а можно использовать готовую системную разметку. Если посмотреть на исходники файла simple_list_item_1.xml в документации Android SDK, то увидим, что он содержит TextView. В этом коде мы создали адаптер ArrayAdapter, в котором данные элемента TextView представлены в виде строк.

Чтобы код был более читаемым, можно сделать ещё так:

Мы вынесли массив строк в отдельную переменную.

Используем ресурсы

Если у нас есть готовый файл ресурсов (массив строк), то можно использовать специальный метод createFromResource(), который может создать ArrayAdapter из ресурсов:

Подготовим массив строк:

Теперь мы можем воспользоваться адаптером и применить к Spinner:

В этом примере мы использовали системную разметку android.R.layout.simple_spinner_item, которая тоже содержит TextView.

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

Или можно пойти другим путём. Получить массив из ресурсов и вставить его в адаптер, как в самом первом примере.

Динамическое наполнение

Также мы можем создать массив программно.

ListAdapter

ListAdapter является интерфейсом. По сути ничего не меняется. Заменяем ArrayAdapter adapter на ListAdapter adapter и получаем тот же результат.

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

SpinnerAdapter

SpinnerAdapter также является интерфейсом и может использоваться при создании собственных адаптеров на основе ArrayAdapter. В стандартных ситуациях смысла использования его нет. Вот так будет выглядеть код:

Переопределяем адаптер

По умолчанию ArrayAdapter использует метод toString() из объекта массива, чтобы наполнять данными элемент TextView, размещённый внутри указанной разметки. Если вы используете ArrayAdapter , где в параметре используется ваш собственный класс, а не String, то можно переопределить метод toString() в вашем классе. Пример такого решения есть в конце статьи Android: Простейшая база данных. Часть вторая.

Другой способ. Мы хотим выводить данные не в одно текстовое поле, а в два. Стандартная разметка для списка с одним TextView нам не подойдёт. Придётся самостоятельно создавать нужную разметку и наполнять её данными.

В этому случае нужно наследоваться от класса ArrayAdapter, указывая конкретный тип и переопределяя метод getView(), в котором указать, какие данные должны вставляться в новой разметке.

Метод getView() принимает следующие параметры: позицию элемента, в котором будет выводиться информация, компонент для отображения данных (или null), а также родительский объект ViewGroup, в котором указанный компонент поместится. Вызов метода getItem() вернёт значение из исходного массива по указанному индексу. В результате метод getView() должен вернуть экземпляр компонента, наполненный данными.

Допустим, у нас есть простой класс Cat с двумя полями — имя и пол. Нашему списку понадобится специальная разметка, состоящая из двух текстовых полей. Создадим адаптер, который будет использовать класс Cat вместо String и будем извлекать данные из объекта класса.

Читайте также:  Android tv box cx 968

Как видите, достаточно просто изменить программу, используя свой класс вместо String.

В методе getView() используется не совсем корректная версия метода inflate(). Подробнее об этом читайте в статье LayoutInflater

Класс ArrayAdapter позволяет динамически изменять данные. Метод add() добавляет в конец массива новое значение. Метод insert() добавляет новое значение в указанную позицию массива. Метод remove() удаляет объект из массива. Метод clear() очистит адаптер. Метод sort() сортирует массив. После него нужно вызвать метод notifyDataSetChanged.

Несколько советов

ArrayAdapter имеет шесть конструкторов.

  • ArrayAdapter(Context context, int resource)
  • ArrayAdapter(Context context, int resource, int textViewResourceId)
  • ArrayAdapter(Context context, int resource, T[] objects)
  • ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
  • ArrayAdapter(Context context, int resource, List objects)
  • ArrayAdapter(Context context, int resource, int textViewResourceId, List objects)

У них у всех первые два параметра — это контекст и идентификатор ресурса для разметки. Если корневой элемент разметки является контейнером вместо TextView, то используйте параметр textViewResourceId, чтобы подсказать методу getView(), какой компонент используется для вывода текста.

Сам адаптер работает с данными, как со списками. Если вы используете стандартный массив, то адаптер переконвертирует его в список. Сами данные необязательно сразу передавать адаптеру, можно сделать это позже через метод addAll().

Другие полезные методы адаптера:

  • add() — добавляет объект в коллекцию
  • remove() — удаляет объект из коллекции
  • getItem(int position) — возвращает объект из позиции position
  • getContext() — получает контекст

На последний метод следует обратить внимание при создании собственного адаптер на основе ArrayAdapter. Не нужно в своём классе объявлять контекст таким образом.

Через метод getContext() вы уже можете получить доступ к контексту, не объявляя новой переменной.

Тоже самое применимо и к массивам. Не нужно объявлять массив:

Используйте метод getItem(position), который может получить доступ к массиву.

Если позволяет логика, используйте списки вместо массивов для большей гибкости. Тогда вы можете добавлять и удалять данные через методы add() и remove().

Источник

SimpleAdapter

Конструктор класса SimpleAdapter имеет следующий вид:

Для данных в параметре data используется коллекция Map-объектов или его наследников, например, HashMap. Каждый Map содержит данные для отдельного элемента списка. Чтобы адаптер понимал, какие данные нужно вставлять в View-компоненты каждого пункта списка, мы указываем два массива from и to. В массиве from используем ключи из Map, а в массиве to – идентификаторы компонентов. Адаптер последовательно перебирает все компоненты из массива to и сопоставляет им соответствующие значения из from. Следите, чтобы в массиве to было не больше элементов, чем в from, иначе программа вызовет ошибку.

Используем системную разметку

При работе с адаптером ArrayAdapter для ListView мы использовали готовую разметку android.R.layout.simple_list_item_1, которая состоит из одного TextView. Существует другая системная разметка android.R.layout.simple_list_item_2, состоящая из двух текстовых меток с идентификаторами android.R.id.text1 и android.R.id.text2, расположенных в двух строчках. В первой метке выводится текст большим шрифтом, а во втором — маленьким.

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

Напишем пример, где у каждого кота будет его имя и телефон.

Мы создали два ключа Name и Tel и программно заполняем их именами котов и их телефонами. Все телефоны вымышлены, не надо звонить по ним! Коты не дают свои номера кому попало.

Используем собственную разметку

Допустим, мы хотим вывести список котов в три колонки: номер, имя кота и его телефон (Ух, ты).

Создадим отдельную разметку для каждого элемента списка:

Читайте также:  Что за клетками андроид

Код для связывания адаптера со списком:

Результат будет следующим:

Изменения минимальны. Мы для каждого кота добавили порядковый номер MemberID, а в адаптере указали не системную, а собственную разметку R.layout.list_item. А также используем массив из трёх элементов.

ListAdapter

В приведённых примерах вы можете безбоязненно заменить SimpleAdapter на ListAdapter:

Это на тот случай, чтобы вы не пугались, если встретите такой код.

Сложная разметка

Разметка может быть любой и включать в себя не только текстовые метки, но и другие компоненты, такие как ImageView и CheckBox. Принцип остаётся такой же. Создаём новую разметку и связываем данные с каждым компонентом.

Создадим новую разметку (или отредактируем файл list_item.xml из предыдущего примера)

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

Смотрим на результат. Я знаю только одного кота, который слушает да ест. Поэтому пометим его как накормленного по умолчанию.

Мы создали два массива, которые будут использованы для сопоставления данных и компонентов. Массив from содержит имена Map-ключей, а массив to – идентификаторы компонентов. Таким образом, в первый TextView с идентификатором R.id.textview_name будет вставлено первое значение ключа CatName и так далее. Аналогично происходит и с другими компонентами CheckBox и ImageView.

Адаптер перебирает все компоненты из массива to для каждого элемента списка и сопоставляет им значения из массива from. Получается такая таблица:

R.id.R.id.textview_name – Map.get(«CatName»)
R.id.checkbox_feed — Map.get(«IsHungry»)
R.id.imageview_cat — Map.get(«Icon»)

Тут возникает интересный вопрос, а как адаптер понимает, какой именно метод нужно вызвать для компонента, чтобы передать ему значение. К примеру, для компонента CheckBox нам нужно установить установить флажок или снять его, а не выводить текст, как для TextView.

Тут о нас уже позаботились. Адаптер смотрит, с чем имеет дело и в зависимости от типа компонента принимает решение. Вариантов немного, всего три.

Первый вариант — если компонент является TextView или его наследником, то вставляется текст. Иными словами, вызывается метод SimpleAdapter.setViewText(), который вызывает TextView.setText() и передает туда нужное значение из Map.

Второй вариант — если компонент, наследует интерфейс Checkable, то адаптер проверяет, является ли соответствующее значение из Map типа boolean. Если это действительно так, то вызывается метод Checkable.setChecked. Если значение не является типом boolean, то проверяется, является ли компонент наследником TextView. Если ответ положительный, то тогда вставляется текстовое значение из Map. В других случаях мы получим ошибку. К компонентам с интерфейсом Checkable относятся CheckBox, CheckedTextView, CompoundButton, RadioButton, Switch, ToggleButton. Вы можете сами в этом убедиться. Заменим блок CheckBox на TextView в разметке list_item.xml:

Запустим проект и увидим следующее:

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

Третий вариант — если компонент является ImageView или его наследником, то проверяется тип данных. Если тип можно привести к типу Integer, то вызывается метод SimpleAdapter.setViewImage(ImageView v, int value), который вызывает метод ImageView.setImageResource(), т.е. подставляется идентификатор ресурса из папки drawable или mipmap. Если тип другой, то вызывается метод SimpleAdapter.setViewImage (ImageView v, String value), который пытается привести значение к int и вызвать метод ImageView.setImageResource(). Если такой вариант не проходит, то преобразует строку в объект Uri и вызывает метод ImageView.setImageURI(Uri).

Если компонент не подходит ни под один из трёх вышеперечисленных типов, то мы получим ошибку.

Продолжим опыты. Допустим, мы хотим не только установить флажок у CheckBox, но и новый текст. Так как мы уже знаем, что наследники TextView могут выводить текст, то поступим следующим образом. В наши массивы from и to добавим новые элементы:

Источник

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