Custom cursoradapter example in android

SimpleCursorAdapter

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

Существует две версии адаптера: android.support.v4.widget.SimpleCursorAdapter и android.SimpleCursorAdapter.

Схема работы адаптера представлена на рисунке.

В левой части представлен компонент на основе класса AdapterView, например, ListView, состоящих из отдельных элементов TextView. В правой части находятся данные, которые могут поступать из базы данных или контент-провайдера. Адаптер берёт по порядку первый элемент списка и первый ряд выбранного столбца из таблицы данных и привязывает их с идентификатором разметки отдельного элемента списка.

Класс SimpleCursorAdapter — это подкласс класса CursorAdapter, который был разработан для облегчения отображения столбцов класса Cursor непосредственно на компоненты TextView или ImagesView, определенные в XML-разметке.

Общий код для адаптера:

Конструктор класса получает следующие параметры:

  • параметр Context, в котором выполняется компонент ListView или ему подобный
  • идентификатор ресурса разметки, который используется для отображения каждого элемента в ListView
  • класс Cursor, который обеспечивает доступ к данным, — этому аргументу можно присвоить значение null, если класс Cursor определяется позже
  • массив String, включающий отображаемые названия столбцов
  • массив типа int, включающий идентификаторы соответствующих ресурсов интерфейса
  • параметр типа int — флаг

Для создания класса SimpleCursorAdapter сначала определите массивы, включающие имена столбцов, для отображения на компоненты GUI. Также следует определить ID ресурсов для компонентов GUI, которые отображают данные из именованных столбцов. В коде создается массив String, показывающий, что может отображаться лишь именованный столбец. Затем создается параллельный массив типа int, содержащий ID ресурсов для соответствующих компонентов GUI. Потом создается класс SimpleCursorAdapter.

Размеры массивов fromColumns и toViews должные совпадать. К примеру, вы можете задать два столбца для извлечения данных и соответственно должны указать два идентификатора, например, для TextView для текста и ImagesView для картинки.

Имейте в виду, что один из конструкторов адаптера теперь устарел. Вы его можете иногда встречать в старых проектах, но копировать в свой проект его не стоит. Дело в том, что его работа происходит в одном потоке с интерфейсом программы и может серьёзно затормозить работу списка. Теперь рекомендуется использовать новый класс CursorLoader, который можно считать аналогом AsyncTask для адаптеров, использующий асинхронные операции. Второй конструктор имеет дополнительный параметр flags. Для быстрой переделки старого кода без использования CursorLoader вы можете просто добавить в код данный флаг CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER или SimpleCursorAdapter.FLAG_AUTO_REQUERY или просто использовать значение 0.

Если стандартный адаптер вас не устраивает, можно его переопределить. Кусок кода из одного проекта.

Источник

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

— используем SimpleCursorAdapter для построения списка
— добавляем и удаляем записи в списке

Важное замечание! Урок более не актуален, т.к. в нем используются методы, которые гугл объявил устаревшими. Если вы просто зашли посмотреть, как использовать SimpleCursorAdapter, то вместо этого урока рекомендую прочитать Урок 136. Если же вы идете последовательно по урокам, то вполне можно прочесть и понять этот урок, а потом просто акутализируете свои знания в Уроке 136.

После нескольких уроков посвященных SimpleAdapter мы знаем про него достаточно и представляем схему его работы. И теперь нам будет нетрудно усвоить SimpleCursorAdapter. Он отличается тем, что в качестве данных используется не коллекция Map, а Cursor с данными из БД. И в массиве from, соответственно, мы указываем не ключи Map-атрибутов, а наименования полей (столбца) курсора. Значения из этих полей будут сопоставлены указанным View-компонентам из массива to.

Читайте также:  Com google android apps gsa tasks m exclusive background task update hotword models crashed

Также немного отличается от SimpleAdapter стандартный биндинг и внешний ViewBinder. SimpleCursorAdapter умеет работать с TextView и ImageView компонентами и их производными, а Checkable-производные не воспримет . А при использовании ViewBinder, необходимо реализовать его метод boolean setViewValue (View view, Cursor cursor, int columnIndex). На вход он принимает View-компонент для биндинга, cursor с данными и номер столбца, из которого надо взять данные. Позиция курсора уже установлена в соответствии с позицией пункта списка. Не буду снова расписывать примеры использования, т.к. они будут очень похожи на примеры из предыдущих уроков по SimpleAdapter. Если там все было понятно, то и здесь проблем не должно возникнуть.

Итак, давайте накидаем пример использования SimpleCursorAdapter. Список будет отображать картинку и текст. Также реализуем возможность добавления и удаления данных из списка. Добавлять будем кнопкой, а удалять с помощью контекстного меню.

Project name: P0521_SimpleCursorAdapter
Build Target: Android 2.3.3
Application name: SimpleCursorAdapter
Package name: ru.startandroid.develop.p0521simplecursoradapter
Create Activity: MainActivity

Обычно в уроках я тексты для кнопок и прочего указывал напрямую. Делал я это не со зла, а чтобы не перегружать урок лишней информацией. Но с последними обновлениями Eclipse стал ругаться примерно так: [I18N] Hardcoded string «какой-то текст», should use @string resource. Ошибка не критична и запуску приложения никак не помешает, но некоторых она смущает. Да и действительно, хардкод – это плохо. С этого урока постараюсь следовать правилам хорошего тона и использовать файлы ресурсов. На нашем текущем уровне знаний это не должно стать помехой в понимании и усвоении уроков.

Тут кроме названия приложения я записал тексты для кнопки и контекстного меню

Кнопка для добавления записи и список.

Layout для пункта списка item.xml:

Картинка и текст.

Т.к. SimpleCursorAdapter – это адаптер для работы с данными из БД, то нам нужно эту БД организовать. Чтобы не загромождать MainActivity.java, я вынесу код по работе с БД в отдельный класс DB. Создаем класс DB.java в том же пакете, где и MainActivity.java

Здесь все нам знакомо по прошлым урокам SQLite.

Мы создаем несколько public методов, чтобы Activity могла через них работать с данными:

open – установить соединение
close – закрыть соединение
getAllData – получить курсор со всеми данными из таблицы
addRec – добавить запись
delRec – удалить запись

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

Вложенный класс DBHelper – для создания и управления БД. В методе onCreate мы создаем таблицу и заполняем ее сгенерированными данными. Метод onUpgrade я оставил пустым, т.к. в этом примере не планирую обновлять версию БД.

Хорошо, что мы создали DB.java. Благодаря ему в MainActivity.java все красиво, прозрачно и удобно. Смотрим код.

В onCreate мы организуем подключение к БД, получаем курсор и просим Activity присмотреть за ним. Теперь при смене Lifecycle-состояний Activity, оно будет менять соответствующим образом состояния курсора. Затем настраиваем биндинг – формируем массивы, которые укажут адаптеру, как сопоставлять данные из курсора и View-компоненты. В R.id.ivImg пойдет значение из поля img, а в R.id.tvText – значение из поля txt. Имена полей мы здесь указываем public-константами класса DB. Далее мы создаем адаптер и настраиваем список на его использование. В конце добавляем контекстное меню к списку.

Читайте также:  Хороший файловый менеджер для андроида

В методе onButtonClick мы генерируем и добавляем запись в БД и обновляем курсор методом requery, чтобы получить свежие данные из БД.

При создании контекстного меню, в методе onCreateContextMenu, мы добавляем пункт для удаления.

В методе onContextItemSelected мы обрабатываем нажатие пункта контекстного меню. Чтобы получить данные по пункту списка, для которого был совершен вызов контекстного меню, мы используем метод getMenuInfo. Объект AdapterContextMenuInfo содержит данные о View, id и позиции пункта списка. Нам нужно id. Этот id равен значению поля _id для соответствующей записи в курсоре. Мы вызываем метод удаления записи и обновляем курсор.

В методе onDestroy мы закрываем подключение к БД. Это будет происходить при закрытии Activity.

Все сохраняем и запускаем.

Нажав на кнопку, мы добавляем запись. А вызвав контекстное меню (долгое нажатие) для пункта списка можно его удалить.

Мы рассмотрели возможность добавления и удаления записей в списке при использовании SimpleCursorAdapter. Возможность редактирования я рассматривать не стал. Это не особо усложнило бы урок, но сделало бы его больше и размыло бы тему. А я стараюсь делать уроки максимально заточенными под конкретную тему. Для тех, кому интересно редактирование – гугл любезно создал такой пример на официальном сайте — http://developer.android.com/resources/tutorials/notepad/index.html. Мой пример похож на него, так что будет проще разобраться.

Кстати, в этом уроке мы встретили список, в котором id пункта может не совпадать с позицией. Для теста попробуйте повесить обработку нажатия на пункт списка и посмотреть, что позиция – это будет позиция пункта в списке, а id – это идентификатор записи из БД (поле _id). Чтобы это работало, необходимо поле-идентификатор в таблице называть _id, т.к. курсор будет использовать его, как id. Иначе получим ошибку.

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

— используем SimpleCursorTreeAdapter для построения списка

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

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

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

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

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

Источник

Populating a ListView with a CursorAdapter

In Android development, any time you want to show a vertical list of items you will want to use a ListView which is populated using an Adapter to a data source. When we want the data for the list to be sourced directly from a SQLite database query, we can use a CursorAdapter.

The CursorAdapter fits in between a Cursor (data source from SQLite query) and the ListView (visual representation) and configures two aspects:

  • Which layout template to inflate for an item
  • Which fields of the cursor to bind to which views in the template

First, we need to define a table within the database from which we will load our cursor. In this case, we will define a database table called todo_items for a collection of todo items with a string body and an integer priority.

body priority
Get milk 2
Do laundry 3

To create this database table, we would use SQLite persistence or an ORM that allows us to define objects mapped to tables.

When we want to display a series of items into a list, using a custom representation of the items, we need to use our own custom XML layout template for each item. We can simply create an XML layout template in res/layout/item_todo.xml , representing a particular cursor row:

Next, we need to define the adapter to describe the process of projecting the Cursor ‘s data into a View. To do this we need to override the newView method and the bindView method. The naive approach to this (without any view caching) looks like the following:

First, we define a constructor that passes the cursor and context to the superclass. Next, we override the newView method, which is used to inflate a new view template. Finally, we override the bindView method, which is used to bind all data to a given view to populate the template content for the item.

In order to use a CursorAdapter , we need to query a SQLite database and get back a Cursor representing the result set. This requires us to use a SQLiteOpenHelper for persistence as described here or an ORM that provides access to the underlying database.

Once you have a database and tables defined, then we can get access to a Cursor by querying the database with rawQuery :

Now, we can use the CursorAdapter in the Activity to display an array of items into the ListView :

This will then trigger the CursorAdapter iterating through the result set and populating the list. We can change the cursor to update the adapter at any time with:

Источник

Android CursorAdapter with custom layout and how to use it

Android provides adapter classes specifically to display data from an SQLite database query. There is SimpleCursorAdapter class, which is more simpler and you cannot use your own custom xml layout and you don’t have the control of the layout. In order to use custom xml layout, Android provides CursorAdapter.

A CursorAdapter makes it easy to use when the resource of a listview is coming from database and you can have more control over the binding of data values to layout controls. In the newView() method, you simply inflate the view and return it. In the bindView() method, you set the elements of your view.

1) CursorAdapter

Create new class

First, create new class which extends CursorAdapter and give it a name. This new CursorAdapter class must implement the inherited abstract methods as following

Next define the methods of MyCursorAdapter

In BaseAdapter, view is created in getView method; in CursorAdapter, however, view is created in newView() method and elements are populated in bindView(). In the newView() method, you simply inflate the view your custom xml and return it. In the bindView() method, you set the elements of your view.
Here is code:

2) MainActivity class

Main Activity setup

Since loading data from database is heavy-duty job, we will load the data in the Thread. If you do not explicitly start CursorAdapter in its own thread then it will run on the main (UI) thread which may be noticeable as jittery or slow to respond interface by your users. Here we’ll use android Handler

Источник

Читайте также:  Android theme background image
Оцените статью