如何将额外的元素插入 SimpleCursorAdapter 或 Spinner 的 Cursor 中?

发布于 2024-11-25 07:02:29 字数 407 浏览 4 评论 0原文

我有一个 Spinner,用于显示从数据库获取的数据列表。数据从查询返回到游标,然后游标被传递到 spinner 的 SimpleCursorAdapter。它工作正常,但我想在此数据之上插入另一个项目。例如,微调器已经显示了保存在数据库中的用户创建的模板列表,但我想在模板列表顶部插入“新模板”和“空模板”,并且需要将其插入到 Cursor/SimpleCursorAdapter 中不知何故。

我考虑过使用数组列表并从游标填充数组列表,但游标对我来说是更好的解决方案,因为它也包含其他相关的数据行。我在互联网上搜索其他解决方案,并找到了一些要求使用 CursorWrapper 来实现此目的的答案,但我找不到如何使用 CursorWrapper 来完成我想要的任务的具体示例。我如何在游标中插入一些行,或者有人可以给出一个易于理解的 CursorWrapper 示例!!提前致谢。

I have a Spinner which is to show a list of data fetched from database. The data is returned to a cursor from query, and the cursor gets passed to spinner's SimpleCursorAdapter. It is working fine as such, but I want to insert another item on top of this data. For example, the spinner is already showing a list of user created templates saved in DB, but I want to insert "New Template" and "Empty Template" on top of the list of templates, and it needs to be inserted into Cursor/SimpleCursorAdapter somehow.

I have considered using an arraylist and populating the arraylist from cursor, but cursor is better solution for me since it contains other related rows of data too. I searched internet for other solutions and found some answers asking to use CursorWrapper for this purpose, but I could not find a concrete example how to use CursorWrapper to accomplish what I want. How can I insert some rows in cursor or can someone please give a easy to follow CursorWrapper example!! Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柏拉图鍀咏恒 2024-12-02 07:02:29

您可以将 MergeCursorMatrixCursor 与数据库 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);

You can use a combination of MergeCursor and MatrixCursor with your DB cursor like this:

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);
笑饮青盏花 2024-12-02 07:02:29

这是我尝试过的方法。

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 一起使用。

This is the method I tried.

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

With this method, you can add any amount of rows anywhere in your cursor. Even though it is not making use of CursorWrapper, it can be used with CursorAdapters or SimpleCursorAdapters.

自由如风 2024-12-02 07:02:29

我尝试了@naktinis提供的解决方案,但结果不是我所期望的。我自己想要实现的目标是作为一个适配器,其中可以在顶部添加新元素(索引 0)。然而,根据给出的解决方案,新元素确实被添加到顶部,但仅添加到 MatrixCursor 的末尾。换句话说,当我动态地将行添加到“extras”MatrixCursor时,我得到了这样的结果:

  • “extras”行1
  • “extras”行2
  • “extras”行3
  • “光标”第1行
  • “光标”第2行
  • “光标”第3行。

但是,我真正想要实现的是这样的:

  • “extras”行3
  • “额外内容” row 2
  • "extras" row 1
  • "cursor" row 1
  • "cursor" row 2
  • "cursor" row 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;
  }
}

I tried the solution provided by @naktinis, but the result wasn't what I expected. What I myself wanted to achieve as an adapter in which new elements can be added at the top (index 0). However, with the solution given, new elements were indeed added at the top but only to the END of the MatrixCursor. In other words, when I added rows dynamically to the "extras" MatrixCursor, I got something like this:

  • "extras" row 1
  • "extras" row 2
  • "extras" row 3
  • "cursor" row 1
  • "cursor" row 2
  • "cursor" row 3.

However, what I really wanted to achieve was something like this:

  • "extras" row 3
  • "extras" row 2
  • "extras" row 1
  • "cursor" row 1
  • "cursor" row 2
  • "cursor" row 3.

In other words, most recent elements enter at the top (index 0).

I was able to achieve this manually by doing the follow. Note that I did not include any logic to handle dynamically removing elements from the adapter.

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;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文