Usando CursorAdapters com Xamarin.Android
O Android fornece classes de adaptador especificamente para exibir dados de uma consulta de banco de dados SQLite:
SimpleCursorAdapter – Semelhante a um ArrayAdapter
porque pode ser usado sem subclasse. Basta fornecer os parâmetros necessários (como um cursor e informações de layout) no construtor e, em seguida, atribuir a um ListView
.
CursorAdapter – Uma classe base que você pode herdar quando precisar de mais controle sobre a associação de valores de dados a controles de layout (por exemplo, ocultar/mostrar controles ou alterar suas propriedades).
Os adaptadores de cursor fornecem uma maneira de alto desempenho de rolar por longas listas de dados armazenados no SQLite. O código de consumo deve definir uma consulta SQL em um Cursor
objeto e, em seguida, descrever como criar e preencher as exibições para cada linha.
Criando um banco de dados SQLite
Para demonstrar adaptadores de cursor, é necessária uma implementação simples de banco de dados SQLite. O código em SimpleCursorTableAdapter/VegetableDatabase.cs contém o código e o SQL para criar uma tabela e preenchê-la com alguns dados.
A classe completa VegetableDatabase
é mostrada aqui:
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();
}
}
A VegetableDatabase
classe será instanciada no OnCreate
método da HomeScreen
atividade. A SQLiteOpenHelper
classe base gerencia a configuração do arquivo de banco de dados e garante que o SQL em seu OnCreate
método seja executado apenas uma vez. Essa classe é usada nos dois exemplos a seguir para SimpleCursorAdapter
e CursorAdapter
.
A consulta do cursor deve ter uma coluna _id
inteira para que funcione CursorAdapter
. Se a tabela subjacente não tiver uma coluna inteira nomeada _id
, use um alias de coluna para outro inteiro exclusivo no RawQuery
que compõe o cursor. Consulte os documentos do Android para obter mais informações.
Criando o cursor
Os exemplos usam a RawQuery
para transformar uma consulta SQL em um Cursor
objeto. A lista de colunas retornada do cursor define as colunas de dados que estão disponíveis para exibição no adaptador de cursor. O código que cria o banco de dados no método SimpleCursorTableAdapter/HomeScreen.cs OnCreate
é mostrado aqui:
vdb = new VegetableDatabase(this);
cursor = vdb.ReadableDatabase.RawQuery("SELECT * FROM vegetables", null); // cursor query
StartManagingCursor(cursor);
// use either SimpleCursorAdapter or CursorAdapter subclass here!
Qualquer código que chame StartManagingCursor
também deve chamar StopManagingCursor
. Os exemplos são usados OnCreate
para iniciar e OnDestroy
fechar o cursor. O OnDestroy
método contém este código:
StopManagingCursor(cursor);
cursor.Close();
Depois que um aplicativo tiver um banco de dados SQLite disponível e tiver criado um objeto de cursor, conforme mostrado, ele poderá utilizar um SimpleCursorAdapter
ou uma subclasse de CusorAdapter
para exibir linhas em um ListView
.
Usando SimpleCursorAdapter
SimpleCursorAdapter
é como o ArrayAdapter
, mas especializado para uso com SQLite. Não requer subclasse - basta definir alguns parâmetros simples ao criar o objeto e, em seguida, atribuí-lo a uma propriedade de Adapter
.ListView
Os parâmetros para o construtor SimpleCursorAdapter são:
Contexto – Uma referência à Atividade que o contém.
Layout – a ID do recurso da exibição de linha a ser usada.
ICursor – Um cursor que contém a consulta SQLite para os dados a serem exibidos.
Da matriz de cadeia de caracteres – Uma matriz de cadeias de caracteres correspondentes aos nomes das colunas no cursor.
Para matriz inteira – uma matriz de IDs de layout que correspondem aos controles no layout de linha. O valor da coluna especificada na from
matriz será associado ao ControlID especificado nessa matriz no mesmo índice.
As from
matrizes e to
devem ter o mesmo número de entradas porque formam um mapeamento da fonte de dados para os controles de layout na exibição.
O código de exemplo SimpleCursorTableAdapter/HomeScreen.cs é conectado SimpleCursorAdapter
assim:
// 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
é uma maneira rápida e simples de exibir dados SQLite em um ListView
arquivo . A principal limitação é que ele só pode vincular valores de coluna a controles de exibição, não permite que você altere outros aspectos do layout da linha (por exemplo, mostrar/ocultar controles ou alterar propriedades).
Subclasse CursorAdapter
Uma CursorAdapter
subclasse tem os mesmos benefícios de desempenho que a SimpleCursorAdapter
exibição de dados do SQLite, mas também oferece controle total sobre a criação e o layout de cada exibição de linha. A CursorAdapter
implementação é muito diferente da subclasse BaseAdapter
porque não substitui GetView
, GetItemId
, Count
ou this[]
indexador.
Dado um banco de dados SQLite em funcionamento, você só precisa substituir dois métodos para criar uma CursorAdapter
subclasse:
BindView – Dada uma exibição, atualize-a para exibir os dados no cursor fornecido.
NewView – Chamado quando o
ListView
requer uma nova exibição para exibição. ElesCursorAdapter
cuidarão das visualizações de reciclagem (ao contrário doGetView
método em adaptadores regulares).
As subclasses de adaptador em exemplos anteriores têm métodos para retornar o número de linhas e recuperar o item atual – o CursorAdapter
não requer esses métodos porque essas informações podem ser obtidas do próprio cursor. Ao dividir a criação e a população de cada visualização nesses dois métodos, o CursorAdapter
reutilização da visualização é obrigatório. Isso contrasta com um adaptador comum, onde é possível ignorar o convertView
BaseAdapter.GetView
parâmetro do método.
Implementando o CursorAdapter
O código em CursorTableAdapter/HomeScreenCursorAdapter.cs contém uma CursorAdapter
subclasse. Ele armazena uma referência de contexto passada para o construtor para que ele possa acessar um LayoutInflater
no NewView
método. A classe completa é assim:
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);
}
}
Atribuindo o CursorAdapter
Activity
No que exibirá o ListView
, crie o cursor e CursorAdapter
atribua-o à exibição de lista.
O código que executa essa ação no método CursorTableAdapter/HomeScreen.cs OnCreate
é mostrado aqui:
// 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);
O OnDestroy
método contém a chamada de StopManagingCursor
método descrita anteriormente.