Używanie elementu CursorAdapters z platformą Xamarin.Android
System Android udostępnia klasy adapterów przeznaczone specjalnie do wyświetlania danych z zapytania bazy danych SQLite:
SimpleCursorAdapter — podobne do elementu , ArrayAdapter
ponieważ można go używać bez podklasy. Wystarczy podać wymagane parametry (takie jak kursor i informacje o układzie) w konstruktorze, a następnie przypisać je do ListView
obiektu .
CursorAdapter — klasa bazowa, z której można dziedziczyć, gdy potrzebujesz większej kontroli nad powiązaniem wartości danych z kontrolkami układu (na przykład ukrywaniem/pokazywaniem kontrolek lub zmienianiem ich właściwości).
Karty kursorów zapewniają wydajny sposób przewijania długich list danych przechowywanych w sqlite. Kod zużywający musi zdefiniować zapytanie SQL w Cursor
obiekcie, a następnie opisać sposób tworzenia i wypełniania widoków dla każdego wiersza.
Tworzenie bazy danych SQLite
Aby zademonstrować adaptery kursorów, wymagana jest prosta implementacja bazy danych SQLite. Kod w pliku SimpleCursorTableAdapter/VegetableDatabase.cs zawiera kod i sql, aby utworzyć tabelę i wypełnić ją pewnymi danymi.
Kompletna VegetableDatabase
klasa jest pokazana tutaj:
class VegetableDatabase : SQLiteOpenHelper {
public static readonly string create_table_sql =
"CREATE TABLE [vegetables] ([_id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, [name] TEXT NOT NULL UNIQUE)";
public static readonly string DatabaseName = "vegetables.db";
public static readonly int DatabaseVersion = 1;
public VegetableDatabase(Context context) : base(context, DatabaseName, null, DatabaseVersion) { }
public override void OnCreate(SQLiteDatabase db)
{
db.ExecSQL(create_table_sql);
// seed with data
db.ExecSQL("INSERT INTO vegetables (name) VALUES ('Vegetables')");
db.ExecSQL("INSERT INTO vegetables (name) VALUES ('Fruits')");
db.ExecSQL("INSERT INTO vegetables (name) VALUES ('Flower Buds')");
db.ExecSQL("INSERT INTO vegetables (name) VALUES ('Legumes')");
db.ExecSQL("INSERT INTO vegetables (name) VALUES ('Bulbs')");
db.ExecSQL("INSERT INTO vegetables (name) VALUES ('Tubers')");
}
public override void OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{ // not required until second version :)
throw new NotImplementedException();
}
}
Klasa VegetableDatabase
zostanie utworzone w OnCreate
metodzie HomeScreen
działania. SQLiteOpenHelper
Klasa bazowa zarządza konfiguracją pliku bazy danych i zapewnia, że baza danych SQL w jej OnCreate
metodzie jest uruchamiana tylko raz. Ta klasa jest używana w następujących dwóch przykładach dla SimpleCursorAdapter
i CursorAdapter
.
Zapytanie kursora musi mieć kolumnę _id
całkowitą, aby CursorAdapter
element działał. Jeśli tabela bazowa nie ma kolumny całkowitej o nazwie _id
, użyj aliasu kolumny dla innej unikatowej liczby całkowitej w RawQuery
obiekcie tworzącym kursor. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją systemu Android.
Tworzenie kursora
W przykładach użyto elementu , RawQuery
aby przekształcić zapytanie SQL w Cursor
obiekt. Lista kolumn zwracana z kursora definiuje kolumny danych, które są dostępne do wyświetlenia na karcie kursora. Kod tworzący bazę danych w metodzie SimpleCursorTableAdapter/HomeScreen.cs OnCreate
jest pokazany tutaj:
vdb = new VegetableDatabase(this);
cursor = vdb.ReadableDatabase.RawQuery("SELECT * FROM vegetables", null); // cursor query
StartManagingCursor(cursor);
// use either SimpleCursorAdapter or CursorAdapter subclass here!
Każdy kod, który wywołuje StartManagingCursor
, powinien również wywołać metodę StopManagingCursor
. Przykłady służą OnCreate
do uruchamiania i OnDestroy
zamykania kursora. Metoda OnDestroy
zawiera następujący kod:
StopManagingCursor(cursor);
cursor.Close();
Gdy aplikacja ma dostępną bazę danych SQLite i utworzyła obiekt kursora, jak pokazano, może używać SimpleCursorAdapter
klasy lub podklasy CusorAdapter
do wyświetlania wierszy w obiekcie ListView
.
Korzystanie z elementu SimpleCursorAdapter
SimpleCursorAdapter
jest jak , ArrayAdapter
ale wyspecjalizowany do użytku z SQLite. Nie wymaga to podklasy — wystarczy ustawić kilka prostych parametrów podczas tworzenia obiektu, a następnie przypisać go do ListView
właściwości .s Adapter
.
Parametry konstruktora SimpleCursorAdapter to:
Context — odwołanie do zawierającego działania.
Layout — identyfikator zasobu widoku wiersza do użycia.
ICursor — kursor zawierający zapytanie SQLite dla danych do wyświetlenia.
Z tablicy ciągów — tablica ciągów odpowiadających nazwam kolumn w kursorze.
Do tablicy całkowitej — tablica identyfikatorów układu odpowiadających kontrolkom w układzie wiersza. Wartość kolumny określonej w from
tablicy będzie powiązana z identyfikatorem ControlID określonym w tej tablicy w tym samym indeksie.
Tablice from
i to
muszą mieć taką samą liczbę wpisów, ponieważ tworzą mapowanie ze źródła danych do kontrolek układu w widoku.
Przykładowy kod SimpleCursorTableAdapter/HomeScreen.cs wykonuje następujące SimpleCursorAdapter
połączenie:
// which columns map to which layout controls
string[] fromColumns = new string[] {"name"};
int[] toControlIDs = new int[] {Android.Resource.Id.Text1};
// use a SimpleCursorAdapter
listView.Adapter = new SimpleCursorAdapter (this, Android.Resource.Layout.SimpleListItem1, cursor,
fromColumns,
toControlIDs);
SimpleCursorAdapter
to szybki i prosty sposób wyświetlania danych SQLite w obiekcie ListView
. Głównym ograniczeniem jest to, że może wiązać tylko wartości kolumny z kontrolkami wyświetlania, nie pozwala na zmianę innych aspektów układu wiersza (na przykład pokazywanie/ukrywanie kontrolek lub zmienianie właściwości).
Podklasowanie CursorAdapter
Podklasa CursorAdapter
ma takie same korzyści jak SimpleCursorAdapter
w przypadku wyświetlania danych z sqlite, ale zapewnia również pełną kontrolę nad tworzeniem i układem każdego widoku wiersza. Implementacja CursorAdapter
różni się bardzo od podklasyBaseAdapter
, ponieważ nie zastępuje GetView
indeksatora , Count
GetItemId
lub this[]
.
Biorąc pod uwagę działającą bazę danych SQLite, wystarczy zastąpić dwie metody tworzenia podklasy CursorAdapter
:
BindView — biorąc pod uwagę widok, zaktualizuj go, aby wyświetlić dane w podanym kursorze.
NewView — wywoływana
ListView
, gdy widok wymaga wyświetlenia nowego widoku. BędzieCursorAdapter
dbać o widoki recyklingu (w przeciwieństwie doGetView
metody na zwykłych adapterach).
Podklasy adaptera we wcześniejszych przykładach mają metody zwracania liczby wierszy i pobierania bieżącego elementu — CursorAdapter
te metody nie wymagają, ponieważ te informacje można zebrać z samego kursora. Dzieląc tworzenie i populację każdego widoku na te dwie metody, CursorAdapter
wymusza ponowne użycie widoku. Jest to w przeciwieństwie do zwykłej karty, w której można zignorować convertView
parametr BaseAdapter.GetView
metody.
Implementowanie elementu CursorAdapter
Kod w pliku CursorTableAdapter/HomeScreenCursorAdapter.cs zawiera podklasę CursorAdapter
. Przechowuje odwołanie kontekstu przekazane do konstruktora, aby mógł uzyskać dostęp do LayoutInflater
obiektu w metodzie NewView
. Kompletna klasa wygląda następująco:
public class HomeScreenCursorAdapter : CursorAdapter {
Activity context;
public HomeScreenCursorAdapter(Activity context, ICursor c)
: base(context, c)
{
this.context = context;
}
public override void BindView(View view, Context context, ICursor cursor)
{
var textView = view.FindViewById<TextView>(Android.Resource.Id.Text1);
textView.Text = cursor.GetString(1); // 'name' is column 1 in the cursor query
}
public override View NewView(Context context, ICursor cursor, ViewGroup parent)
{
return this.context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, parent, false);
}
}
Przypisywanie elementu CursorAdapter
W okienkuListView
, w ramach Activity
którego zostanie wyświetlony element , utwórz kursor, a CursorAdapter
następnie przypisz go do widoku listy.
Kod wykonujący tę akcję w metodzie CursorTableAdapter/HomeScreen.cs OnCreate
jest pokazany tutaj:
// create the cursor
vdb = new VegetableDatabase(this);
cursor = vdb.ReadableDatabase.RawQuery("SELECT * FROM vegetables", null);
StartManagingCursor(cursor);
// create the CursorAdapter
listView.Adapter = (IListAdapter)new HomeScreenCursorAdapter(this, cursor, false);
Metoda OnDestroy
zawiera StopManagingCursor
opisane wcześniej wywołanie metody.