- ArrayAdapter
- Создание адаптера
- Используем ресурсы
- Динамическое наполнение
- ListAdapter
- SpinnerAdapter
- Переопределяем адаптер
- Несколько советов
- Адаптеры и списки
- ListView и ArrayAdapter
- Введение
- ListView и ArrayAdapter
- 1. Создаем в Android Studio проект на базе шаблона EmptyActivity.
- 2. В layout файл Activity добавляем ListView.
- 3. Создаем объект для хранения данных и заполняем его.
- 4. Создаем layout одного элемента списка.
- 5. Создаем адаптер и передаем его ListView.
- 6. Получаем ссылку на ListView и передаем ему адаптер.
- 7. Добавляем обработчики нажатий — listener объекты.
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 и будем извлекать данные из объекта класса.
Как видите, достаточно просто изменить программу, используя свой класс вместо 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().
Источник
Адаптеры и списки
ListView и ArrayAdapter
Android представляет широкую палитру элементов,которые представляют списки. Все они является наследниками класса android.widget.AdapterView . Это такие виджеты как ListView, GridView, Spinner. Они могут выступать контейнерами для других элементов управления
При работе со списками мы имеем дело с тремя компонентами. Во-первых, это визуальный элемент или виджет, который на экране представляет список (ListView, GridView) и который отображает данные. Во-вторых, это источник данных — массив, объект ArrayList, база данных и т.д., в котором находятся сами отображаемые данные. И в-третьих, это адаптер — специальный компонент, который связывает источник данных с виджетом списка.
Одним из самых простых и распространенных элементов списка является виджет ListView . Рассмотрим связь элемента ListView с источником данных с помощью одного из таких адаптеров — класса ArrayAdapter .
Класс ArrayAdapter представляет собой простейший адаптер, который связывает массив данных с набором элементов TextView , из которых, к примеру, может состоять ListView . То есть в данном случае источником данных выступает массив объектов. ArrayAdapter вызывает у каждого объекта метод toString() для приведения к строковому виду и полученную строку устанавливает в элемент TextView.
Посмотрим на примере. Итак, разметка приложения может выглядеть так:
Здесь также определен элемент ListView, который будет выводить список объектов. Теперь перейдем к коду activity и свяжем ListView через ArrayAdapter с некоторыми данными:
Здесь вначале получаем по id элемент ListView и затем создаем для него адаптер.
Для создания адаптера использовался следующий конструктор ArrayAdapter (this,android.R.layout.simple_list_item_1, countries) , где
this : текущий объект activity
android.R.layout.simple_list_item_1 : файл разметки списка, который фреймворк представляет по умолчанию. Он находится в папке Android SDK по пути platforms/[android-номер_версии]/data/res/layout. Если нас не удовлетворяет стандартная разметка списка, мы можем создать свою и потом в коде изменить id на id нужной нам разметки
countries : массив данных. Здесь необязательно указывать именно массив, это может быть список ArrayList .
В конце неоходимо установить для ListView адаптер с помощью метода setAdapter() .
Источник
Введение
Одна из частых задач, возникающих при программировании Android приложений, — это отображение на дисплее набора данных. Например, списка пользователей, содержимого папки, набора заметок и так далее. Для решения данной задачи в составе Android SDK есть такие компоненты как ListView, GridView, RecyclerView. В этой статье речь пойдет об использовании ListView. Этот компонент на данный момент является самым распространенным.
Итак, ListView предназначен для отображения набора данных в виде одномерного (в один столбец) списка. Принцип работы данного компонента состоит в том, что он создает несколько View элементов, достаточных для отображения видимой части списка и затем переиспользует их (то есть заполняет новыми данными), когда пользователь скролит список.
Созданием View элементов списка и заполнением их данными занимается адаптер — объект, который реализует интерфейс Adapter. Он создается разработчиком на этапе конфигурирования ListView. В составе Android SDK уже есть несколько готовых адаптеров, работающих «из коробки», например ArrayAdapter, SimpleAdapter, CursorAdapter. Также разработчик может написать свой, так называемый custom адаптер, что обычно и приходится делать.
Базовая схема использования ListView выглядит так:
- прописываем ListView в требуемый layout файл Activity или Fragment
- создаем объект для хранения данных и заполняем его данными
- создаем layout для одного элемента списка
- создаем адаптер, передав ему набор данных и layout одного элемента списка
- получаем ссылку на ListView и передаем ему адаптер
- добавляем обработчики событий, например OnItemClickListener
Попробуем написать простое приложение с ListView и ArrayAdapter.
ListView и ArrayAdapter
1. Создаем в Android Studio проект на базе шаблона EmptyActivity.
File > New > New Project. далее следуем указаниям визарда.
Я создал проект с такими параметрами:
- Application name: ListViewTest1
- Company Domain: codeandlife.ru
- Platforms: Phone and Tablet — API15:Android4.0.3 (IceCreamSandwich)
- Template: EmptyActivity
2. В layout файл Activity добавляем ListView.
По умолчанию AndroidStudio создает файл разметки с RelativeLayout и TextView. Меняем RelativeLayout на FrameLayout, а TextView на ListView. Должен получиться примерно такой код:
id нужен для того чтобы получить ссылку на ListView в коде.
layout_width и layout_height задают размеры Listview. В данном случае ListView займет все пространство, которое ему предоставит FrameLayout.
3. Создаем объект для хранения данных и заполняем его.
Тип объекта, используемого для хранения данных, определяется типом используемого адаптера. ArrayAdapter может работать с массивами или коллекциями, реализующими List интерфейс. Если разработчик создает свой адаптер, он может использовать произвольные объекты, например xml файл.
Мы будем использовать ArrayList и набор строк. Код будет выглядеть так:
Замечание! На этапе создания адаптера и конфигурирования ListView, данные для отображения могут отсутствовать, например, если они подгружаются из базы данных или удаленного веб-сервиса. В этом нет ничего необычного, их можно добавить и потом. Этот момент будет разобран в следующих статьях.
4. Создаем layout одного элемента списка.
Для этого в AndroidStudio нажимаем правой кнопкой мыши на папке res > layout и создаем новый Layout resource file.
ArrayAdapter умеет работать только с макетами, в которых есть только одно текстовое поле для заполнения. Обычно это TextView. В макете могут присутствовать другие View элементы, но ArrayAdapter не сможет ничего с ними сделать.
Наш макет будет выглядеть так:
id нужен для того, чтобы адаптер мог получить ссылку на TextView (хотя если макет состоит из одного TextView, то этот параметр можно опустить)
layout_with и layout_height задают размеры TextView. В данном случае он растянется по горизонтали на всю ширину, предоставленную родительским компонентом (ListView), а по высоте будет равен высоте текста + padding параметр.
padding – задается в dp (density-independent pixel) единицах и представляет собой пространство между текстом и внешней границей TextView
textSize – определяет размер текста и задается в sp (scale-independent pixel) единицах
Замечание! Android SDK имеет собственный набор ресурсов (картинки, макеты, наборы цветов и так далее), которые разработчик может использовать в своих приложениях. В данном случае мы могли бы применить готовый макет android.R.layout.simple_list_item_1, который имеет такую же структуру — один TextView.
5. Создаем адаптер и передаем его ListView.
Адаптер — это объект, создающий View объект на основе переданного ему layout файла и заполняющий этот объект данными. В этой роли может выступать класс, который реализует интерфейс Adapter. Для упрощения задачи, мы используем готовый класс адаптера — ArrayAdapter. Это самый простой адаптер в Android SDK, поэтому с него и стоит начать знакомство.
Класс ArrayAdapter имеет несколько конструкторов, нам подойдут вот такие:
context – это объект, который используется адаптером для создания View объектов на основе переданного макета. Обычно здесь передается ссылка на Activity.
resource – это id макета элемента списка, то есть id layout файла.
textViewResouceId – id элемента, отображающего текст. В нашем случае это id TextView.
objects – ссылка на коллекцию, содержащую данные
Если layout элемента списка состоит только из TextView (как в нашем случае), достаточно первого конструктора. Если layout более сложный (из нескольких View объектов), нужно использовать второй конструктор и передавать адаптеру id текстового поля.
В нашем случае код будет выглядеть так:
6. Получаем ссылку на ListView и передаем ему адаптер.
Тут все просто, ссылку на View объект в Activity мы получаем с помощью метода findViewById(int id).
Все. С этого момента ListView уже будет работать. Можно загрузить приложение в телефон или эмулятор и убедиться в этом.
7. Добавляем обработчики нажатий — listener объекты.
Имея ссылку на ListView, разработчик может назначить ему обработчики событий. Наиболее часто используемые события — это кратковременное нажатие на элемент списка и длительное нажатие. Для регистрации обработчиков этих событий используются следующие методы:
Эти методы принимают ссылки на объекты, реализующие интерфейсы OnItemClickListener и OnItemLongClickListener. Каждый интерфейс содержит по одному методы, которые будут вызываться ListView при наступлении соответствующего события. Для интерфейса OnItemClickListener метод выглядит так:
parent – ссылка на ListVew
view – ссылка на view объект, на который было произведено нажатие.
position – позиция view в адаптере
id – идентификационный номер элемента списка, обычно совпадает с position.
Самый простой вариант добавления обработчика состоит в использовании анонимного класса. Вот так:
Многие разработчики не любят подобное нагромождение кода и предпочитают реализовать требуемый интерфейс в Activity (или Fragment) и передавать ссылку на нее. Вот так:
В обработчике события обычно выполняется какая-либо работа с нажатым View или данными, соответствующими этому элементу списка. Получить данные из обработчика можно несколькими способами. Самый простой способ состоит в использовании ссылки на объект, в котором хранит данные. В нашем случае это ссылка на ArrayList.
Также можно получить данные, использую объект parent, который передается обработчику. На мой взгляд — это более правильный способ доступа к данным.
Источник