如何将额外元素插入到 SimpleCursorAdapter 或 Spinner 的光标中?

Posted

技术标签:

【中文标题】如何将额外元素插入到 SimpleCursorAdapter 或 Spinner 的光标中?【英文标题】:How to insert extra elements into a SimpleCursorAdapter or Cursor for a Spinner? 【发布时间】:2011-10-08 22:59:30 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

您可以将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);

【讨论】:

太棒了。这比像其他人建议的那样将光标加载到数组列表中要好得多。谢谢。 是否需要关闭extrascursor游标?【参考方案2】:

这是我试过的方法。

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

【讨论】:

【参考方案3】:

我尝试了@naktinis 提供的解决方案,但结果不是我所期望的。作为一个适配器,我自己想要实现的目标是可以在顶部添加新元素(索引 0)。但是,在给出解决方案的情况下,确实在顶部添加了新元素,但仅添加到了 MatrixCursor 的 END。换句话说,当我将行动态添加到“附加”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;
  

【讨论】:

以上是关于如何将额外元素插入到 SimpleCursorAdapter 或 Spinner 的光标中?的主要内容,如果未能解决你的问题,请参考以下文章

上采样:在向量的每个连续元素之间插入额外的值

如何使用额外的列执行“插入到 select *”查询?

如何将点击事件添加到插入的元素

ASP.NET Core API - 如何在映射后将额外字段插入数据库

如何将元素插入到特定位置的数组中?

如何将字符串数组的元素动态插入到 textview 中并定位它?