Uso di CursorAdapter con Xamarin.Android
Android fornisce classi di adattatori specifiche per visualizzare i dati da una query di database SQLite:
SimpleCursorAdapter : simile a un ArrayAdapter
perché può essere usato senza sottoclasse. Specificare semplicemente i parametri obbligatori (ad esempio un cursore e le informazioni sul layout) nel costruttore e quindi assegnare a un oggetto ListView
.
CursorAdapter : classe di base da cui è possibile ereditare quando è necessario un maggiore controllo sul binding dei valori dei dati ai controlli di layout, ad esempio nascondere o visualizzare i controlli o modificarne le proprietà.
Gli adattatori cursori offrono un modo ad alte prestazioni per scorrere gli elenchi lunghi di dati archiviati in SQLite. Il codice di utilizzo deve definire una query SQL in un Cursor
oggetto e quindi descrivere come creare e popolare le viste per ogni riga.
Creazione di un database SQLite
Per illustrare gli adattatori di cursore, è necessaria una semplice implementazione del database SQLite. Il codice in SimpleCursorTableAdapter/VegetableDatabase.cs contiene il codice e SQL per creare una tabella e popolarlo con alcuni dati.
La classe completa VegetableDatabase
è illustrata di seguito:
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();
}
}
La VegetableDatabase
classe verrà creata un'istanza OnCreate
nel metodo dell'attività HomeScreen
. La SQLiteOpenHelper
classe base gestisce l'installazione del file di database e garantisce che SQL nel metodo OnCreate
venga eseguito una sola volta. Questa classe viene usata nei due esempi seguenti per SimpleCursorAdapter
e CursorAdapter
.
Per il funzionamento della query del cursore, è necessario che la query del cursore disponga di una colonna _id
CursorAdapter
integer. Se nella tabella sottostante non è presente una colonna integer denominata _id
, usare un alias di colonna per un altro numero intero univoco in RawQuery
che costituisce il cursore. Per altre informazioni, vedere la documentazione di Android.
Creazione del cursore
Gli esempi usano un RawQuery
oggetto per trasformare una query SQL in un Cursor
oggetto . L'elenco di colonne restituito dal cursore definisce le colonne di dati disponibili per la visualizzazione nell'adattatore di cursore. Il codice che crea il database nel metodo SimpleCursorTableAdapter/HomeScreen.cs OnCreate
è illustrato di seguito:
vdb = new VegetableDatabase(this);
cursor = vdb.ReadableDatabase.RawQuery("SELECT * FROM vegetables", null); // cursor query
StartManagingCursor(cursor);
// use either SimpleCursorAdapter or CursorAdapter subclass here!
Qualsiasi codice che chiama StartManagingCursor
deve chiamare StopManagingCursor
anche . Gli esempi usano OnCreate
per avviare e OnDestroy
per chiudere il cursore. Il OnDestroy
metodo contiene questo codice:
StopManagingCursor(cursor);
cursor.Close();
Una volta che un'applicazione dispone di un database SQLite disponibile e ha creato un oggetto cursore come illustrato, può utilizzare una SimpleCursorAdapter
sottoclasse o di CusorAdapter
per visualizzare le righe in un oggetto ListView
.
Uso di SimpleCursorAdapter
SimpleCursorAdapter
è come , ArrayAdapter
ma specializzato per l'uso con SQLite. Non richiede la sottoclasse: è sufficiente impostare alcuni parametri semplici durante la creazione dell'oggetto e quindi assegnarlo alla proprietà di Adapter
un ListView
oggetto .
I parametri per il costruttore SimpleCursorAdapter sono:
Context : riferimento all'attività contenitore.
Layout : ID risorsa della visualizzazione riga da usare.
ICursor : cursore contenente la query SQLite per visualizzare i dati.
Dalla matrice di stringhe: matrice di stringhe corrispondenti ai nomi delle colonne nel cursore.
Matrice integer: matrice di ID di layout che corrispondono ai controlli nel layout di riga. Il valore della colonna specificata nella from
matrice verrà associato all'ELEMENTO ControlID specificato in questa matrice nello stesso indice.
Le from
matrici e to
devono avere lo stesso numero di voci perché formano un mapping dall'origine dati ai controlli di layout nella visualizzazione.
Il codice di esempio SimpleCursorTableAdapter/HomeScreen.cs collega un SimpleCursorAdapter
codice simile al seguente:
// 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
è un modo semplice e veloce per visualizzare i dati SQLite in un oggetto ListView
. La limitazione principale è che può associare solo i valori di colonna ai controlli di visualizzazione, non consente di modificare altri aspetti del layout di riga , ad esempio la visualizzazione o la disattivazione dei controlli o la modifica delle proprietà.
Sottoclasse CursorAdapter
Una CursorAdapter
sottoclasse offre gli stessi vantaggi in termini di prestazioni di SimpleCursorAdapter
per la visualizzazione dei dati da SQLite, ma offre anche il controllo completo sulla creazione e il layout di ogni visualizzazione riga. L'implementazione CursorAdapter
è molto diversa dalla sottoclasse BaseAdapter
perché non esegue l'override GetView
di , GetItemId
Count
o this[]
dell'indicizzatore.
Dato un database SQLite funzionante, è sufficiente eseguire l'override di due metodi per creare una CursorAdapter
sottoclasse:
BindView : data una visualizzazione, aggiornarla per visualizzare i dati nel cursore fornito.
NewView : chiamato quando richiede
ListView
una nuova visualizzazione da visualizzare. L'oggettoCursorAdapter
si occuperà di riciclare le viste (a differenza delGetView
metodo sugli adapter normali).
Le sottoclassi dell'adapter negli esempi precedenti includono metodi per restituire il numero di righe e recuperare l'elemento corrente. CursorAdapter
Non è necessario che questi metodi vengano recuperati perché tali informazioni possono essere recuperate dal cursore stesso. Suddividendo la creazione e il popolamento di ogni visualizzazione in questi due metodi, la CursorAdapter
visualizzazione viene applicata di nuovo. Si tratta di un adattatore normale in cui è possibile ignorare il convertView
parametro del BaseAdapter.GetView
metodo .
Implementazione di CursorAdapter
Il codice in CursorTableAdapter/HomeScreenCursorAdapter.cs contiene una CursorAdapter
sottoclasse. Archivia un riferimento di contesto passato al costruttore in modo che possa accedere a un LayoutInflater
oggetto nel NewView
metodo . La classe completa è simile alla seguente:
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);
}
}
Assegnazione del CursorAdapter
Activity
In che visualizzerà , ListView
creare il cursore e CursorAdapter
assegnarlo alla visualizzazione elenco.
Il codice che esegue questa azione nel metodo CursorTableAdapter/HomeScreen.cs OnCreate
è illustrato di seguito:
// 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);
Il OnDestroy
metodo contiene la chiamata al StopManagingCursor
metodo descritta in precedenza.