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.
Также немного отличается от 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 для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Using CursorAdapters with Xamarin.Android
Android provides adapter classes specifically to display data from an SQLite database query:
SimpleCursorAdapter – Similar to an ArrayAdapter because it can be used without subclassing. Simply provide the required parameters (such as a cursor and layout information) in the constructor and then assign to a ListView .
CursorAdapter – A base class that you can inherit from when you need more control over the binding of data values to layout controls (for example, hiding/showing controls or changing their properties).
Cursor adapters provide a high-performance way to scroll through long lists of data that are stored in SQLite. The consuming code must define an SQL query in a Cursor object and then describe how to create and populate the views for each row.
Creating an SQLite Database
To demonstrate cursor adapters requires a simple SQLite database implementation. The code in SimpleCursorTableAdapter/VegetableDatabase.cs contains the code and SQL to create a table and populate it with some data. The complete VegetableDatabase class is shown here:
The VegetableDatabase class will be instantiated in the OnCreate method of the HomeScreen activity. The SQLiteOpenHelper base class manages the setup of the database file and ensures that the SQL in its OnCreate method is only run once. This class is used in the following two examples for SimpleCursorAdapter and CursorAdapter .
The cursor query must have an integer column _id for the CursorAdapter to work. If the underlying table does not have an integer column named _id then use a column alias for another unique integer in the RawQuery that makes up the cursor. Refer to the Android docs for further information.
Creating the Cursor
The examples use a RawQuery to turn an SQL query into a Cursor object. The column list that is returned from the cursor defines the data columns that are available for display in the cursor adapter. The code that creates the database in the SimpleCursorTableAdapter/HomeScreen.cs OnCreate method is shown here:
Any code that calls StartManagingCursor should also call StopManagingCursor . The examples use OnCreate to start, and OnDestroy to close the cursor. The OnDestroy method contains this code:
Once an application has a SQLite database available and has created a cursor object as shown, it can utilize either a SimpleCursorAdapter or a subclass of CusorAdapter to display rows in a ListView .
Using SimpleCursorAdapter
SimpleCursorAdapter is like the ArrayAdapter , but specialized for use with SQLite. It does not require subclassing – just set some simple parameters when creating the object and then assign it to a ListView ’s Adapter property.
The parameters for the SimpleCursorAdapter constructor are:
Context – A reference to the containing Activity.
Layout – The resource ID of the row view to use.
ICursor – A cursor containing the SQLite query for the data to display.
From string array – An array of strings corresponding to the names of columns in the cursor.
To integer array – An array of layout IDs that correspond to the controls in the row layout. The value of the column specified in the from array will be bound to the ControlID specified in this array at the same index.
The from and to arrays must have the same number of entries because they form a mapping from the data source to the layout controls in the view.
The SimpleCursorTableAdapter/HomeScreen.cs sample code wires up a SimpleCursorAdapter like this:
SimpleCursorAdapter is a fast and simple way to display SQLite data in a ListView . The main limitation is that it can only bind column values to display controls, it does not allow you to change other aspects of the row layout (for example, showing/hiding controls or changing properties).
Subclassing CursorAdapter
A CursorAdapter subclass has the same performance benefits as the SimpleCursorAdapter for displaying data from SQLite, but it also gives you complete control over the creation and layout of each row view. The CursorAdapter implementation is very different from subclassing BaseAdapter because it does not override GetView , GetItemId , Count or this[] indexer.
Given a working SQLite database, you only need to override two methods to create a CursorAdapter subclass:
BindView – Given a view, update it to display the data in the provided cursor.
NewView – Called when the ListView requires a new view to display. The CursorAdapter will take care of recycling views (unlike the GetView method on regular Adapters).
The adapter subclasses in earlier examples have methods to return the number of rows and to retrieve the current item – the CursorAdapter does not require these methods because that information can be gleaned from the cursor itself. By splitting the creation and population of each view into these two methods, the CursorAdapter enforces view re-use. This is in contrast to a regular adapter where it’s possible to ignore the convertView parameter of the BaseAdapter.GetView method.
Implementing the CursorAdapter
The code in CursorTableAdapter/HomeScreenCursorAdapter.cs contains a CursorAdapter subclass. It stores a context reference passed into the constructor so that it can access a LayoutInflater in the NewView method. The complete class looks like this:
Assigning the CursorAdapter
In the Activity that will display the ListView , create the cursor and CursorAdapter then assign it to the list view.
The code that performs this action in the CursorTableAdapter/HomeScreen.cs OnCreate method is shown here:
The OnDestroy method contains the StopManagingCursor method call described previously.
Источник