【问题标题】:setSelection on Spinner based on rowId基于 rowId 在 Spinner 上设置选择
【发布时间】:2010-04-01 10:13:16
【问题描述】:

我有一个通过 SimpleCursorAdapter 填充的微调器视图。

根据选择,我需要将 rowid 保存在条目数据库中(位置不起作用,因为可以从 Spinner 数据库中添加和删除内容)。

我可以使用 spinner.getAdapter().getItemId(pos); 来做到这一点。但是当我编辑一个条目时,我需要选择与此 rowid 关联的 Spinner 位置(当前)。

spinner.setSelection(position); 不起作用,因为我有 rowid,我需要一种方法来根据数据库中的 rowid 找到项目在当前微调器中的当前位置。

【问题讨论】:

  • 我已经更新了答案,检查一下。

标签: database android spinner


【解决方案1】:

如果您想设置由CursorAdapter 支持的Spinner 的选择,您可以遍历Cursor 中的所有项目并查找您想要的项目(假设您的主键表名为“_id”):

Spinner spinner = (Spinner) findViewById(R.id.spinner);
spinner.setAdapter(new SimpleCursorAdapter(...));

for (int i = 0; i < spinner.getCount(); i++) {
    Cursor value = (Cursor) spinner.getItemAtPosition(i);
    long id = value.getLong(value.getColumnIndex("_id"));
    if (id == rowid) {
        spinner.setSelection(i);
    }
}

如果要获取选中项的rowid,可以做类似的事情:

Cursor cursor = (Cursor) spinner.getSelectedItem();
long rowid = cursor.getLong(cursor.getColumnIndex("_id"));

可能有更快的方法来做这件事,但这对我来说总是有效的。

【讨论】:

  • 别忘了管理这些游标,要么自己关闭它们,要么让android使用startManagingCursor来处理,免去我刚才的头痛。
  • 第 6 行缺少 ')'。编译器显示 ')' expected
  • @ErichDouglass 不错的解决方案。
  • @Timbermar 编辑了这一行:long id = value.getLong(value.getColumnIndex("_id");,末尾带有)
  • 还有其他方法吗?如果有超过 50k 个城市,我该怎么办。
【解决方案2】:

写这篇文章的时候有个想法,在填充微调器时用 rowid->pos 制作了一个哈希表,然后使用它。如果有人正在搜索,可能会有所帮助。

【讨论】:

    【解决方案3】:

    我同意上面的Erich Douglass's answer 但我发现最快的循环语法在 spinner.getCount() 大于 50k 到 100k 时会很有用

    /* 1 (fastest) */
    for (int i = initializer; i >= 0; i--) { ... }
    
    /* 2 */
    int limit = calculateLoopLimit();
    for (int i = 0; i < limit; i++) { ... }
    
    /* 3 */
    Type[] array = getMyArray();
    for (Type obj : array) { ... }
    
    /* 4 */
    for (int i = 0; i < array.length; i++) { ... }
    
    /* 5 */
    for (int i = 0; i < this.var; i++) { ... }
    
    /* 6 */
    for (int i = 0; i < obj.size(); i++) { ... }
    
    /* 7 (slowest) */
    Iterable<Type> list = getMyList();
    for (Type obj : list) { ... }
    

    所以我认为我们可以在这里使用第二个以获得更好的性能:

    int spinnerCount = spinner.getCount();
    for (int i = 0; i < spinnerCount; i++) {
        Cursor value = (Cursor) spinner.getItemAtPosition(i);
        long id = value.getLong(value.getColumnIndex("_id"));
        if (id == rowid) {
            spinner.setSelection(i);
        }
    }
    

    【讨论】:

      【解决方案4】:

      我认为暂时不要使用 for 循环,因为当你找到你的项目时,可以打破循环。

      int spinnerCount = spinner.getCount();
      int i = 0;
      while(i++ < spinnerCount) {
          Cursor value = (Cursor) spinner.getItemAtPosition(i);
          long id = value.getLong(value.getColumnIndex("_id"));
          if (id == rowid) {
              spinner.setSelection(i);
              break;
          }
      }
      

      【讨论】:

        【解决方案5】:

        第一步,为您的数据集创建视图,包括连接等:

        CREATE VIEW my_view AS
          SELECT _id, field FROM my_table
        

        第二步:

        CREATE VIEW my_view2 AS
          SELECT count(*) AS row_id, q1.*
          FROM my_view AS q1
          LEFT JOIN my_view AS q2
          WHERE q1._id >= q2._id
          GROUP BY q1._id
        

        那么简单:

        SELECT * FROM my_view2
        

        结果:

        row_id | _id | field
        
        1   4   XbMCmUBFwb
        2   6   Te JMejSaK
        3   8   dDGMMiuRuh
        4   10  phALAbnq c
        5   11  EQQwPKksIj
        6   12  PAt tbDnf
        7   13  f zUSuhvM
        8   14  TIMBgAGhkT
        9   15  OOcnjKLLER
        

        通过 id 获取位置:

        SELECT * FROM my_view2 WHERE _id=11
        

        结果:

        row_id | _id | field
        
        5   11  EQQwPKksIj
        

        希望有所帮助

        【讨论】:

          【解决方案6】:

          https://stackoverflow.com/a/5040748/1206052

          dziobas

          提供了一个很棒的答案..但我并不奇怪为什么没有人推荐它..只是想在他的答案中做一些更正..

          CREATE VIEW my_view2 AS
            SELECT count(*) AS row_id, q1.*
            FROM my_view AS q1
            LEFT JOIN my_view AS q2
            ON (q1._id >= q2._id)
            GROUP BY q1._id
          

          我刚刚将“where”替换为 join 所需的“on”..

          现在你有所有的项目,他们的位置与那里的 ID 相关联..

          只需将 ROW_id 分配给 spinner 的setselection()

          【讨论】:

            【解决方案7】:

            既然你能以正确的方式做事,为什么还要以艰难的方式去做呢?

            我参考手册:

            http://d.android.com/reference/android/widget/AdapterView.OnItemSelectedListener.html#onItemSelected%28android.widget.AdapterView%3C?%3E,%20android.view.View,%20int,%20long%29

            示例代码:

            spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
                    public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
                    {
                        int index = spinner.getSelectedItemPosition();
                        Toast.makeText(getBaseContext(), 
                            "You have selected item : " + index + " which is row " + id, 
                            Toast.LENGTH_SHORT).show();                
                    }
                    public void onNothingSelected(AdapterView<?> arg0) {}
                });
            

            感谢 #android-dev 上的 evancharlton 的启发。 :)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-05-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多