Получение _id строк в ListVew справа - PullRequest
2 голосов
/ 06 января 2012

У меня есть ListView, который показывает кучу значений из таблицы SQLite.Сначала я использовал SimpleCursorAdapter для заполнения ListView на основе курсора из запроса SQL.Я переключился на использование SimpleAdapter вместо, потому что мне пришлось манипулировать / добавлять данные в список перед отправкой на ListView.

При использовании SimpleCursorAdapter идентификатор, возвращаемый из ListView после нажатия строки, является правильным идентификатором из таблицы базы данных, но при использовании SimpleAdapter идентификатор выглядит так, как если бы он был сгенерирован ListViewпотому что это то же самое, что и позиция.

Моя таблица выглядит следующим образом:

_id | col1 | col2 | col3

Метод создания курсора для SimpleCursorAdapter выглядит следующим образом:

public Cursor fetchDataAsCursor()
{
  return db.query("table_name", new String[] { "_id", "col1", "col2"}, null, null, null, null, null);
}

Метод заполнения ListView с использованием SimpleCursorAdapter выглядит следующим образом:

  private void simpleFillData()
  {
    Cursor cursor = dbAdapter.fetchDataAsCursor();
    startManagingCursor(cursor);

    String[] from = new String[] {"col1", "col2"};
    int[] to = new int[] {R.id.col1, R.id.col2};

    SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
        R.layout.list_row, cursor, from, to);
    setListAdapter(notes);
  }

Это прекрасно работает, так как возвращенный идентификатор в порядке в следующем методе:

  protected void onListItemClick(ListView l, View v, int position, long id)
  {
    super.onListItemClick(l, v, position, id);
    Intent i = new Intent(this, DetailActivity.class);
    i.putExtra("_id", id);
    startActivityForResult(i, ACTIVITY_EDIT);
  }

Теперь переключаемся на SimpleAdapter.

Код для создания List:

  public ArrayList<HashMap<String, Object>> getList()
  {
    ArrayList <HashMap<String, Object>> list = new ArrayList();

    c = fetchDataAsCursor();
    c.moveToFirst();
    for(int i = 0; i < c.getCount(); i++)
    {    
      HashMap<String, Object> h = new HashMap<String, Object>();
      h.put("_id", c.getLong(0));
      h.put("col1", c.getString(1));
      h.put("col2", c.getString(2));

      //This is the extra column
      h.put("extra", calculateSomeStuff(c.getString(1), c.getString(2));
      list.add(h);
      c.moveToNext();
    }

    return list;
  }

А затем для метода, который заполняет ListView:

private void fillData()
  {
    ArrayList<HashMap<String, Object>> list = dbAdapter.getList();
    String[] from = new String[] {"col1", "col2", "extra"};
    int[] to = new int[] {R.id.col1, R.id.col2, R.id.extra};
    SimpleAdapter notes = new SimpleAdapter(this, list, R.layout.list_row, from, to);
    setListAdapter(notes);
  }

В этом последнем методе ListView не удается подобрать значение _id в списке.Я бы предположил, что он будет делать это автоматически, как и при использовании SimpleCursorAdapter

. Есть ли способ манипулировать идентификатором строки в ListView, чтобы быть уверенным, что она имеет то же значение?как ключ _id в таблице базы данных?

(Все примеры кода значительно упрощены)

Редактировать:

Я понял.Я должен был сделать свой собственный подкласс SimpleAdapter, который переопределяет public long getItemId(int position)

public class MyListAdapter extends SimpleAdapter
{
  private final String ID = "_id";
  public PunchListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
  {
    super(context, data, resource, from, to);
  }

  @Override
  public long getItemId(int position)
  {
    Object o = getItem(position);
    long id = position;
    if(o instanceof Map)
    {
      Map m = (Map)o;
      if(m.containsKey(ID))
      {
        o = m.get(ID);
        if(o instanceof Long)
          id = (Long)o;
      }
    } 
    return id;
  }
}

1 Ответ

0 голосов
/ 22 февраля 2013

Это плохой способ работы с курсором с помощью SimpleAdapter.Вы должны реализовать CursorAdapter.

public class MyCursorAdapter extends CursorAdapter
{
      LayoutInflater inflater;
      public MyCursorAdapter(Context context, Cursor c) {
        super(context, c);
        inflater = LayoutInflater.from(context);
      }

 @Override
          public void bindView(View view, Context context, Cursor cursor) {
            //cursor is already setted to requared position, just get your column
            TextView tv1 = (TextView)view.findViewById(R.id.textView1);
            TextView tv2 = (TextView)view.findViewById(R.id.textView2);
            tv1.setText(cursor.getString(1));
            tv2.setText(cursor.getString(2));
            viev.addOnClickListener(new OnClickListener{
                 public void onClick(View v){
                    ...
                    cursor.getLong(0);
                    ...
                 }
            });       
          }

@Override
      public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return inflater.inflate(R.layout.my_raw_view, parent, false);
      }
    }

Чем просто установить адаптер для просмотра списка в вашей деятельности.

Cursor cursor = fetchDataAsCursor();
    ListView myListView = (ListView)findViewById(R.id.my_list_view);
    myListView.setAdapter(new MyCursorAdapter(this,cursot));
...