Partilhar via


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 ListViewarquivo . 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. Eles CursorAdapter cuidarão das visualizações de reciclagem (ao contrário do GetView 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.