次の方法で共有


Xamarin.Android での CursorAdapters の使用

Android には、SQLite データベース クエリからのデータを詳細に表示するためのアダプター クラスが用意されています。

SimpleCursorAdapter – サブクラス化せずに使用できるため、ArrayAdapter に似ています。 コンストラクターに必要なパラメーター (カーソルやレイアウト情報など) を指定し、ListView に割り当てるだけです。

CursorAdapter – レイアウト コントロールへのデータ値のバインドをより詳細に制御する必要がある場合に継承できる基本クラス (コントロールの非表示/表示、プロパティの変更など)。

カーソル アダプターには、SQLite に格納されているデータの長いリストをスクロールするためのフォーマンスの高い方法が用意されています。 使用するコードでは、Cursor オブジェクトで SQL クエリを定義し、各行のビューを作成して設定する方法を記述しておく必要があります。

SQLite データベースの作成

カーソル アダプターの実証には、単純な SQLite データベースの実装が必要です。 SimpleCursorTableAdapter/VegetableDatabase.cs のコードには、テーブルを作成してデータを設定するコードと SQL が含まれています。 完全な VegetableDatabase クラスを次に示します。

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();
   }
}

VegetableDatabase クラスは、HomeScreen アクティビティの OnCreate メソッドでインスタンス化されます。 SQLiteOpenHelper 基底クラスはデータベース ファイルの設定を管理し、その OnCreate メソッドで SQL が 1 回だけ実行されるようにします。 このクラスは、次の SimpleCursorAdapterCursorAdapter の 2 つの例で使用されます。

カーソルクエリには、CursorAdapter を機能させるための整数列 _id が含まれる必要があります。 基になるテーブルに _id という名前の整数列がない場合は、カーソルを構成する RawQuery 内の別の一意の整数に対して列の別名を使用します。 詳細については、Android のドキュメントを参照してください。

カーソルの作成

この例では、RawQuery を使用して SQL クエリを Cursor オブジェクトに変換します。 カーソルから返される列のリストは、カーソル アダプターに表示できるデータ列を定義します。 SimpleCursorTableAdapter/HomeScreen.csOnCreate メソッドでデータベースを作成するコードを次に示します。

vdb = new VegetableDatabase(this);
cursor = vdb.ReadableDatabase.RawQuery("SELECT * FROM vegetables", null); // cursor query
StartManagingCursor(cursor);
// use either SimpleCursorAdapter or CursorAdapter subclass here!

StartManagingCursor を呼び出すコードでは、StopManagingCursor も呼び出す必要があります。 例では、OnCreate を使用して開始し、OnDestroy でカーソルを閉じています。 OnDestroy メソッドには、次のコードが含まれています。

StopManagingCursor(cursor);
cursor.Close();

アプリケーションで SQLite データベースを使用でき、以下に示すようにカーソル オブジェクトを作成したら、SimpleCursorAdapter または CusorAdapter のサブクラスを使用して ListView に行を表示できます。

SimpleCursorAdapter の使用

SimpleCursorAdapterArrayAdapter に似ていますが、SQLite での使用に特化しています。 サブクラス化は必要ありません。オブジェクトの作成時にいくつかの単純なパラメーターを設定し、それを ListViewAdapter プロパティに割り当てるだけです。

SimpleCursorAdapter コンストラクターのパラメーターは次のとおりです。

Context – 含まれるアクティビティへの参照。

Layout – 使用する行ビューのリソース ID。

ICursor – 表示するデータの SQLite クエリを含むカーソル。

文字列の配列から - カーソル内の列の名前に対応する文字列の配列。

文字列の配列 - 行レイアウトのコントロールに対応するレイアウト ID の配列。 from 配列で指定された列の値は、同じインデックスでこの配列で指定された ControlID にバインドされます。

from 配列と to 配列は、データ ソースからビュー内のレイアウト コントロールへのマッピングを形成するため、同じ数のエントリを持つ必要があります。

SimpleCursorTableAdapter/HomeScreen.cs サンプル コードは、次のように SimpleCursorAdapter を接続します。

// 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 は、ListView で SQLite データを表示するための高速かつ簡単な方法です。 主な制限は、列の値をバインドしてコントロールを表示できることだけであり、行レイアウトの他の側面 (コントロールの表示/非表示、プロパティの変更など) を変更することはできません。

CursorAdapter のサブクラス化

CursorAdapter サブクラスには SQLite からのデータを表示するための SimpleCursorAdapter と同じパフォーマンス上の利点がありますが、各行ビューの作成とレイアウトを完全に制御することもできます。 CursorAdapter の実装は、GetViewGetItemIdCountthis[] インデクサーをオーバーライドしないため、BaseAdapter のサブクラス化とは大きく異なります。

動作する SQLite データベースの場合、CursorAdapter サブクラスを作成するには、次の 2 つのメソッドのみをオーバーライドする必要があります。

  • BindView – ビューを指定した場合は、指定されたカーソルにデータを表示するようにビューを更新します。

  • NewViewListView で新しいビューを表示する必要がある場合に呼び出されます。 CursorAdapter はビューのリサイクルを処理します (通常のアダプターでの GetView メソッドとは異なります)。

前の例のアダプター サブクラスには、行数を返すメソッドと、現在の項目を取得するメソッドがあります。情報は、カーソル自体から収集できるため、CursorAdapter でこれらのメソッドは必要ありません。 各ビューの作成と設定をこれら 2 つのメソッドに分割することで、CursorAdapter で強制的にビューが再利用されます。 これは、BaseAdapter.GetView メソッドの convertView パラメーターを無視できる通常のアダプターとは対照的です。

CursorAdapter の実装

CursorTableAdapter/HomeScreenCursorAdapter.cs のコードには、CursorAdapter サブクラスが含まれています。 また、NewView メソッドで LayoutInflater にアクセスできるように、コンストラクターに渡されたコンテキスト参照が格納されます。 完全なクラスは次のようになります。

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);
   }
}

CursorAdapter の割り当て

ListView を表示する Activity では、カーソル CursorAdapter を作成し、リスト ビューに割り当てます。

CursorTableAdapter/HomeScreen.csOnCreate メソッドでこのアクションを実行するコードを次に示します。

// 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);

OnDestroy メソッドには、前に説明した StopManagingCursor メソッド呼び出しが含まれています。