android - studio - ¿Cómo insertar elementos adicionales en un SimpleCursorAdapter o Cursor para un Spinner?
simplecursoradapter deprecated (4)
Encontré algo de información sobre la adición de elementos a la rueda giratoria que tiene SimpleCursorAdapter: http://groups.google.com/group/android-developers/browse_thread/thread/4123868e02fc9172
Tengo un Spinner que muestra una lista de datos obtenidos de la base de datos. Los datos se devuelven a un cursor desde la consulta, y el cursor pasa al SimpleCursorAdapter de la ruleta. Está funcionando bien como tal, pero quiero insertar otro elemento sobre estos datos. Por ejemplo, la rueda giratoria ya muestra una lista de plantillas creadas por el usuario guardadas en la base de datos, pero quiero insertar "Nueva plantilla" y "Plantilla vacía" en la parte superior de la lista de plantillas, y debe insertarse en Cursor / SimpleCursorAdapter de algun modo.
He considerado usar un arraylist y poblar el arraylist desde el cursor, pero el cursor es la mejor solución para mí, ya que también contiene otras filas de datos relacionadas. Busqué en Internet otras soluciones y encontré algunas respuestas solicitando el uso de CursorWrapper para este propósito, pero no pude encontrar un ejemplo concreto de cómo usar CursorWrapper para lograr lo que quiero. ¿Cómo puedo insertar algunas filas en el cursor o alguien puede dar un ejemplo fácil de seguir de CursorWrapper? Gracias por adelantado.
Este es el método que probé.
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);
}
Con este método, puede agregar cualquier cantidad de filas en cualquier lugar del cursor. Aunque no utiliza CursorWrapper, puede utilizarse con CursorAdapters o SimpleCursorAdapters.
Probé la solución provista por @naktinis, pero el resultado no fue el esperado. Lo que yo mismo quería lograr como adaptador en el que se pueden agregar nuevos elementos en la parte superior (índice 0). Sin embargo, con la solución dada, se agregaron nuevos elementos en la parte superior, pero solo al FINAL del MatrixCursor. En otras palabras, cuando agregué filas dinámicamente al "extra" MatrixCursor, obtuve algo como esto:
- "extras" fila 1
- "extras" fila 2
- "extras" fila 3
- "cursor" fila 1
- "cursor" fila 2
- "cursor" fila 3.
Sin embargo, lo que realmente quería lograr era algo como esto:
- "extras" fila 3
- "extras" fila 2
- "extras" fila 1
- "cursor" fila 1
- "cursor" fila 2
- "cursor" fila 3.
En otras palabras, los elementos más recientes entran en la parte superior (índice 0).
Pude lograr esto manualmente haciendo lo siguiente. Tenga en cuenta que no incluí ninguna lógica para manejar la eliminación dinámica de elementos del adaptador.
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;
}
}
Puedes usar una combinación de MergeCursor
y MatrixCursor
con el cursor
tu base de datos de la siguiente manera:
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);