Как вставить дополнительные элементы в SimpleCursorAdapter или Cursor для Spinner?

У меня есть Spinner, который должен отображать список данных, извлеченных из базы данных. Данные возвращаются в курсор из запроса, и курсор передается в SimpleCursorAdapter счетчика. Он отлично работает как таковой, но я хочу вставить другой элемент поверх этих данных. Например, счетчик уже показывает список созданных пользователем шаблонов, сохраненных в БД, но я хочу вставить «Новый шаблон» и «Пустой шаблон» поверх списка шаблонов, и его нужно вставить в Cursor/SimpleCursorAdapter. как-то.

Я рассматривал возможность использования массива и заполнения массива из курсора, но курсор для меня является лучшим решением, поскольку он также содержит другие связанные строки данных. Я искал в Интернете другие решения и нашел несколько ответов с просьбой использовать CursorWrapper для этой цели, но я не смог найти конкретного примера того, как использовать CursorWrapper для достижения того, что я хочу. Как я могу вставить несколько строк в курсор или кто-нибудь может дать простой пример CursorWrapper !! Заранее спасибо.


person elto    schedule 19.07.2011    source источник


Ответы (4)


Вы можете использовать комбинацию MergeCursor и MatrixCursor с вашей БД cursor следующим образом:

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);
person naktinis    schedule 31.01.2013
comment
Потрясающий. Это намного лучше, чем загрузка курсора в массив, как предлагали другие. благодаря. - person Thupten; 30.05.2013
comment
Пожалуйста, выберите это как ответ. Это избавило меня от многих проблем по сравнению с другим вариантом, упомянутым в других вопросах (с использованием mergeadapter). - person Shushu; 12.06.2013
comment
После реализации этого (я и руководство) Я: Вся ваша база принадлежит нам! :D - person Skynet; 21.02.2014
comment
Серьезно круто. Спасибо! - person Shmuel; 09.07.2014
comment
Нужно ли закрывать курсоры extras и cursor? - person ban-geoengineering; 25.01.2017

Это метод, который я пробовал.

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.

person syy    schedule 14.01.2014

Я попробовал решение, предоставленное @naktinis, но результат оказался не таким, как я ожидал. Чего я сам и хотел добиться в качестве адаптера, в котором новые элементы можно добавлять вверху (индекс 0). Однако с данным решением новые элементы действительно были добавлены вверху, но только в КОНЕЦ MatrixCursor. Другими словами, когда я динамически добавлял строки в «extras» MatrixCursor, я получил что-то вроде этого:

  • строка "дополнительно" 1
  • строка "дополнительно" 2
  • строка "дополнительно" 3
  • "курсор" строка 1
  • "курсор" строка 2
  • «курсорная» строка 3.

Однако то, чего я действительно хотел добиться, было примерно так:

  • строка "дополнительно" 3
  • строка "дополнительно" 2
  • строка "дополнительно" 1
  • "курсор" строка 1
  • "курсор" строка 2
  • «курсорная» строка 3.

Другими словами, самые последние элементы помещаются вверху (индекс 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;
  }
}
person Daniel Gabriele    schedule 30.09.2014

Я нашел некоторую информацию о добавлении элемента в счетчик с SimpleCursorAdapter: http://groups.google.com/group/android-developers/browse_thread/thread/4123868e02fc9172

person Tautvydas    schedule 14.01.2012