Condividi tramite


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 StopManagingCursoranche . 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 , ArrayAdapterma 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 ListViewoggetto .

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 GetViewdi , GetItemIdCount 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'oggetto CursorAdapter si occuperà di riciclare le viste (a differenza del GetView 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à , ListViewcreare 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.