- Введение
- ListView и ArrayAdapter
- 1. Создаем в Android Studio проект на базе шаблона EmptyActivity.
- 2. В layout файл Activity добавляем ListView.
- 3. Создаем объект для хранения данных и заполняем его.
- 4. Создаем layout одного элемента списка.
- 5. Создаем адаптер и передаем его ListView.
- 6. Получаем ссылку на ListView и передаем ему адаптер.
- 7. Добавляем обработчики нажатий — listener объекты.
- ListView в Android: Кастомизация списков
- Пример: ListActivity с собственным шаблоном.
- Пример: ListActivity с гибким шаблоном
- Продвинутые ListActivity
- Мультивыбор
- Хедер и Футер
- SimpleCursorAdapter
Введение
Одна из частых задач, возникающих при программировании 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, который передается обработчику. На мой взгляд — это более правильный способ доступа к данным.
Источник
ListView в Android: Кастомизация списков
Продолжение статьи о ListView в Android, в котором мы рассмотрим более сложные примеры его использования, такие, как иконки на элементах списка и добавление чекбоксов к этим элементам. Так же мы рассмотрим возможности по оптимизации кода.
Напомню, что статья является переводом этой статьи с разрешения ее автора.
Пример: ListActivity с собственным шаблоном.
Вы можете создать свой собственный шаблон для элементов списка и применить его к своему Адаптеру. Шаблон будет одинаковым для каждого элемента списка, но дальше мы разберем как сделать его более гибким. В нашем примере мы добавим иконку к каждому элементу списка.
Создайте файл шаблона «rowlayout.xml» в папке res/layout вашего проекта «de.vogella.android.listactivity».
Измените свою Деятельность на следующую. Код почти такой же, как и в предыдущем примере, единственная разница в том, что мы используем наш собственный шаблон в ArrayAdapter и указываем адаптеру какой элемент пользовательского интерфейса будет содержать текст. Мы не делали этого в предидущей статье, поскольку мы использовали стандартный шаблон.
Пример: ListActivity с гибким шаблоном
Оба предыдущих примера используют один шаблон сразу для всех строк. Если вы хотите изменить вид определенных строк, вам нужно определить свой адаптер и заместить метод getView().
Этот метод ответственен за создание отдельных элементов вашего ListView. getView() возвращает Вид. Этот Вид фактически является Шаблоном (ViewGroup) и содержит в себе другие Виды, например, ImageView или TextView. С getView() вы так же можете изменить параметры индивидуальных видов.
Чтобы прочитать шаблон из XML в getView(), вы можете использовать системный сервис LayoutInflator.
В этом примере мы расширяем ArrayAdapter, но так же мы можем реализовать непосредственно BaseAdapter.
Определение простого адаптера
Очень просто создать свой Адаптер, не обращая внимания на его оптимизацию. Просто получайте в своей Деятельности данные, которые хотите отобразить и сохраняйте их в элемент списка. В вашем getView() установите ваш предопределенный шаблон для элементов и получите нужные вам элементы с помощью findViewById(). После этого вы можете определить их свойства.
Наш пример использует две картинки: «no.png» и «ok.png». Я положил их в папку «res/drawable-mdpi». Используйте свои картинки. Если не нашли таковых, то просто скопируйте «icon.png» и, с помощью графического редактора, немного измените их.
Создайте класс «MySimpleArrayAdapter», который будет служить нашим Адаптером.
Чтобы использовать этот Адаптер, измените класс MyList на следующее
Когда вы запустите это приложение, вы увидите список с элементами, с разными значками на некоторых из них.
Оптимизация производительности вашего собственного адаптера
Создание Java объектов для каждого элемента — это увеличение потребления памяти и временные затраты. Как уже говорилось, Андроид стирает элементы (виды) вашего списка, которые уже не отображаются и делегируют управление ими в метод getView() через параметр convertView.
Ваш Адаптер может использовать этот вид и избежать «раздутие» Шаблона для этого элемента. Это сохраняет память и уменьшает загрузку процессора.
В вашей реализации вы должны проверять convertView на наличие содержимого и переназначать его, отправляя новые данные в существующий Шаблон, если convertView не пустой.
Наша реализация так же использует модель ViewHolder. Метод findViewById() достаточно ресурсоемок, так что нужно избегать его, если в нем нет прямой необходимости.
ViewHolder сохраняет ссылки на необходимые в элементе списка Шаблоны. Этот ViewHolder прикреплен к элементу методом setTag(). Каждый Вид может содержать примененную ссылку. Если элемент очищен, мы можем получить ViewHolder через метод getTag(). Это выглядит нагруженным, но, на самом деле, работает быстрее, чем повторяющиеся вызовы findViewById().
Обе техники (переназначение существующих видов и модель ViewHolder) увеличивают производительность примерно на 15%, особенно на больших объемах данных.
Продолжая использовать проект «de.vogella.android.listactivity», создайте класс «MyArrayAdapter.java».
Продвинутые ListActivity
Обработка долгого нажатия на элементе
Вы так же можете добавить LongItemClickListener к виду. Для этого получите ListView через метод getListView() и определите обработку длительного нажатия через метод setOnItemLongClickListener().
Элементы, взаимодействующие с моделью данных
Ваш шаблон элемента списка так же может содержать Виды, взаимодействующие с моделью данных. Например, вы можете использовать Checkbox в элементе списка и, если чекбокс включен, вы можете менять данные, отображаемые в элементе.
Мы до сих пор используем тот же проект. Создайте шаблон элемента списка «rowbuttonlayout.xml».
создайте для этого примера класс Model, который содержит название элемента и его содержимое, если он чекнут.
Создайте следующий Адаптер. Этот Адаптер добавит обработку изменения Checkbox. Если чекбокс включен, то данные в модели тоже меняются. Искомый Checkbox получает свою модель через метод setTag().
В завершение измените свой ListView на следующий.
Когда вы запустите ваше приложение, вам будет доступна отметка элементов, которая будет отражаться на вашей модели.
Мультивыбор
Так же можно сделать одиночный и мультивыбор. Посмотрите следующие сниппеты для примера. Чтобы получить выбранные элементы используйте listView.getCheckedItemPosition() или listView.getCheckedItemPositions(). Вы так же можете использовать listView.getCheckedItemIds(), чтобы получить ID выбранных элементов.
Хедер и Футер
Вы можете поместить произвольные элементы вокруг своего списка. Например, вы можете создать шаблон со списком между двумя TextView. Если вы так сделаете, то вы должны указать id «@android:id/list» к ListView, т.к. ListActivity ищет Вид с таким идентификатором. В таком случае один TextView всегда будет видимым над ListView (Хедер), а другой будет виден внизу. Если вы хотите использовать Футер и Хедер только в конце/начале списка, чтобы они не были фиксированными, то нужно использовать view.setHeaderView() или view.setFooterView(), например:
SimpleCursorAdapter
Если вы работаете с базой данных или же с контентом непосредственно, вы можете использовать SimpleCursorAdapter, чтобы перенести данные в ваш ListView.
Создайте новый проект «de.vogella.android.listactivity.cursor» с деятельностью «MyListActivity». Создайте такую деятельность.
Убедитесь, что вы дали приложению доступ к контактам. (Используйте «android.permission.READ_CONTACTS» в AndroidManifest.xml).
Спасибо за внимание. Комментарии и поправки к переводу приветствуются, т.к. даже в исходнике встречаются ошибки и опечатки.
Прошу прощения за репост, изначально не отметил как перевод, поскольку недавно здесь. Большое спасибо за наводку jeston, принял к сведению и научился на ошибках.
Источник