データベースからフェッチされたデータのリストを表示するスピナーがあります。データはクエリからカーソルに返され、カーソルはスピナーのSimpleCursorAdapterに渡されます。それ自体は正常に機能していますが、このデータの上に別の項目を挿入したいと思います。たとえば、スピナーはすでにDBに保存されているユーザー作成テンプレートのリストを表示していますが、テンプレートのリストの上に「新しいテンプレート」と「空のテンプレート」を挿入したいので、カーソル/ SimpleCursorAdapterに挿入する必要があります何とかして。
配列リストを使用し、カーソルから配列リストにデータを入力することを検討しましたが、カーソルには他の関連するデータ行も含まれているため、カーソルの方が優れたソリューションです。インターネットで他の解決策を検索し、この目的でCursorWrapperを使用するように求める回答をいくつか見つけましたが、CursorWrapperを使用して目的を達成する具体的な例を見つけることができませんでした。カーソルにいくつかの行を挿入するにはどうすればよいですか、または誰かがCursorWrapperの例を簡単に理解できるようにしてください!!前もって感謝します。
MergeCursor
とMatrixCursor
の組み合わせをDBcursor
で次のように使用できます。
MatrixCursor extras = new MatrixCursor(new String[] { "_id", "title" });
extras.addRow(new String[] { "-1", "New Template" });
extras.addRow(new String[] { "-2", "Empty Template" });
Cursor[] cursors = { extras, cursor };
Cursor extendedCursor = new MergeCursor(cursors);
@naktinisが提供するソリューションを試しましたが、期待した結果ではありませんでした。一番上(インデックス0)に新しい要素を追加できるアダプターとして私自身が達成したかったこと。ただし、与えられたソリューションでは、新しい要素が実際に上部に追加されましたが、MatrixCursorの末尾にのみ追加されました。つまり、「エクストラ」MatrixCursorに動的に行を追加すると、次のようになります。
しかし、私が本当に達成したかったのは、次のようなものでした。
つまり、最新の要素が一番上(インデックス0)に入力されます。
以下を行うことで、これを手動で実現することができました。アダプターから要素を動的に削除する処理を行うロジックが含まれていないことに注意してください。
private class CollectionAdapter extends ArrayAdapter<String> {
/**
* This is the position which getItem uses to decide whether to fetch data from the
* DB cursor or directly from the Adapter's underlying array. Specifically, any item
* at a position lower than this offset has been added to the top of the adapter
* dynamically.
*/
private int mCursorOffset;
/**
* This is a SQLite cursor returned by a call to db.query(...).
*/
private Cursor mCursor;
/**
* This stores the initial result returned by cursor.getCount().
*/
private int mCachedCursorCount;
public Adapter(Context context, Cursor cursor) {
super(context, R.layout.collection_item);
mCursor = cursor;
mCursorOffset = 0;
mCachedCursorCount = -1;
}
public void add(String item) {
insert(item, 0);
mCursorOffset = mCursorOffset + 1;
notifyDataSetChanged();
}
@Override
public String getItem(int position) {
// return the item directly from underlying array if it was added dynamically.
if (position < mCursorOffset) {
return super.getItem(position);
}
// try to load a row from the cursor.
if (!mCursor.moveToPosition(position - mCursorOffset)) {
Log.d(TAG, "Failed to move cursor to position " + (position - mCursorOffset));
return null; // this shouldn't happen.
}
return mCursor.getString(INDEX_COLLECTION_DATA);
}
@Override
public int getCount() {
if (mCachedCursorCount == -1) {
mCachedCursorCount = mCursor.getCount();
}
return mCursorOffset + mCachedCursorCount;
}
}
これが私が試した方法です。
MatrixCursor m = new MatrixCursor(c.getColumnNames());
Cursor c = DBHelper.rawQuery("Select values from your_table");
MatrixCursor m = new MatrixCursor(c.getColumnNames());
//Use MatrixCursor#addRow here to add before the original cursor
while (c.moveToNext()) {
//Use MatrixCursor#addRow here to add before the original row
DBHelper.insertRow(c, m);
//Use MatrixCursor#addRow here to add after the original row
}
//Use MatrixCursor#addRow here to add after the original cursor
m.addRow(new String[]{col1Val, col2Val, col3Val,..., //to match the number of columns needed});
DBHelper.insertRow()
public final static void insertRow(Cursor from, MatrixCursor to) {
final String columns[] = from.getColumnNames(), values[] = new String[columns.length];
final int size = columns.length;
for (int i = 0; i < size; i++) {
values[i] = getStringFromColumn(from, columns[i]);
}
to.addRow(values);
}
この方法では、カーソルの任意の場所に任意の数の行を追加できます。 CursorWrapperを使用していませんが、CursorAdaptersまたはSimpleCursorAdaptersで使用できます。
SimpleCursorAdapterを持つスピナーに要素を追加することに関するいくつかの情報を見つけました: http://groups.google.com/group/Android-developers/browse_thread/thread/4123868e02fc9172