Всем привет! Эта статтья будет о прекрасном адаптере под названием SimpleCursorAdapter который помогает связать данные из бд со списком ListView. Эта статтья является как бы продолжением предыдущей ("Пишем свой SQLiteOpenHelper"), так как с той бд мы связываем наш адаптер и "прикручиваем" его к списку.
Для начала напомню что у нас есть объект-контейнер в который "кладутся" данные из бд:
public class Shop { private int id; private String title; private double price; public Shop() { } public Shop(String _title, double _price) { title = _title; price = _price; } public Shop(int _id, String _title, double _price) { id = _id; title = _title; price = _price; } public void setId(int _id) { id = _id; } public void setTitle(String _title) { title = _title; } public void setPrice(double _price) { price = _price; } public int getId() { return id; } public String getTitle() { return title; } public double getPrice() { return price; } }Определим для нашего списка главный лейаут:
<ListView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#2898FA"> </ListView>
Так же определим ещё один лейаут, он будет ячейкой списка. В ячейке будет два TextView, один для названия товара, другой для цены:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <TextView android:id="@+id/titleTV" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:padding="8dp" android:background="#32D1D6" android:textColor="#000000" /> <TextView android:id="@+id/priceTV" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:padding="8dp" android:background="#32D1D6" android:textColor="#000000" /> </LinearLayout>
Всё, марафет навели. Теперь будем разбираться что же всё таки такое SimpleCursorAdapter. Что нам нужно? Нужно определить класс (назовём его MyCursorAdapter) и расширить его SimpleCursorAdapter'ом. В SimpleCursorAdapter'e есть обязательный конструктор, который выглядит так:
public MyCursorAdapter(Context _context, int _layout, Cursor _cursor, String[] _from, int[] _to) { super(_context, _layout, _cursor, _from, _to); layout = _layout; }
Не важно какой конструктор мы напишем, главное вызвать наследуемый конструктор в который следует передать: 1) текущий контекст; 2) лейаут ячейки; 3) курсор который указывает на данные из бд; 4) названия столбцов с которых следует взять данные; 5) view которые следует заполнить. Немножко не ясно, но потом когда нарисуется вся картина всё прояснится.
Значит наследуя класс SimpleCursorAdapter мы должны реализовать миниммум два метода. Первый называется newView:
@Override public View newView(Context _context, Cursor _cursor, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) _context.getSystemService(_context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(layout, parent, false); return view; }
Этот метод создаёт view-ячейку. В качестве параметров ему передаём текущий контекст, курсор и элементы-родителя. В самом методе нам следует определить view ячейки, что мы и делаем с помощью LayoutInflater. На перёд забегая скажу что методы SimpleCursorAdapter'a не вызываются явно пользователем, они вызываются адаптером автоматически.
Второй метод будет "вешать" данные в ячейку:
@Override public void bindView(View view, Context _context, Cursor _cursor) { String title = _cursor.getString(_cursor.getColumnIndex(AppData.COLUMN_TITLE)); Double price = Double.parseDouble(_cursor.getString(_cursor.getColumnIndex(AppData.COLUMN_PRICE))); TextView titleTV = (TextView) view.findViewById(R.id.titleTV); TextView priceTV = (TextView) view.findViewById(R.id.priceTV); titleTV.setText(title); priceTV.setText(price.toString() + "$"); }
В качестве параметров ему передаётся view которую мы создали в предыдущем методе, текущий контекст и курсор. В первую очередь достаём необходимые данные из курсора, далее вставляем их в наши две TextView. Всё, как видим ничего сложного! Полностью класс MyCursorAdapter будет выглядеть так:
import android.content.Context; import android.database.Cursor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.SimpleCursorAdapter; import android.widget.TextView; public class MyCursorAdapter extends SimpleCursorAdapter { private int layout; public MyCursorAdapter(Context _context, int _layout, Cursor _cursor, String[] _from, int[] _to) { super(_context, _layout, _cursor, _from, _to); layout = _layout; } //связывает данные с view на которые указывает курсор @Override public void bindView(View view, Context _context, Cursor _cursor) { String title = _cursor.getString(_cursor.getColumnIndex(AppData.COLUMN_TITLE)); Double price = Double.parseDouble(_cursor.getString(_cursor.getColumnIndex(AppData.COLUMN_PRICE))); TextView titleTV = (TextView) view.findViewById(R.id.titleTV); TextView priceTV = (TextView) view.findViewById(R.id.priceTV); titleTV.setText(title); priceTV.setText(price.toString() + "$"); } //сoздаёт нвоую view для хранения данных на которую указывает курсор @Override public View newView(Context _context, Cursor _cursor, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) _context.getSystemService(_context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(layout, parent, false); return view; } }
Теперь переходим в главное активити которое наследуется от ListActivity. Там нам следует провести инициализацию.
private void init() { String[] from = { AppData.COLUMN_TITLE, AppData.COLUMN_PRICE }; int[] to = { R.id.titleTV, R.id.priceTV }; db = new DBHelper(this, AppData.DATABASE_NAME, null, 1); Cursor cursor = db.getAllCursor(); adapter = new MyCursorAdapter(this, R.layout.item_listview, cursor, from, to); getListView().setAdapter(adapter); getListView().setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.i("MyTag", "position = " + position + " && id = " + id); } }); }
В первую очередь нам нужно подготовить данные для конструктора адаптера: from - необходимые столбцы из бд; to - эелементы куда вставлять данные взятые из from; db - наш DBHelper из предыдущего урока; cursor - получаем данные таблицы из бд. Далее вызываем конструктор адаптера и присваиваем своему списку адаптер. Так же создаём обработчик onItemClick для нашего списка, где в лог для наглядности будем выводить позицию в списке и айди из бд.
Скриншот программы:
На первом скриншоте видим что данные успешно и красиво загрузились. На втором же скриншоте продемонстрирован лог в который выводятся данные при нажатии на ячейки. Как видим разницу между position и id. Position - позиция нажатой ячейки в списке (начинается снуля). Id - айдишник из бд. Это наверное главный плюс этой всей затеей, так как при клике по ячейке списка мы уже знаем айди данной записи в бд и уже с этой записью можем делать всё что захочем.
Проект можно скачать по ссылкам:
Хороша стаття. Опублікую ссилку в соц. мережі
ВідповістиВидалити