У меня есть 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;
}
}