问题描述
我有一个恼人的问题与SimpleCursorAdapter。我PROGRAMM拥有列表视图和ListActivity。每一行都有自己的布局:
I have ONE annoying problem with SimpleCursorAdapter. My programm has list view and ListActivity. Each row has it's own layout:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:layout_width="fill_parent"
android:orientation="horizontal" android:weightSum="1.0">
<TableRow>
<TextView android:id="@+id/task_time"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textSize="24sp" android:text="Time">
</TextView>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent">
<TextView android:id="@+id/task_name"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textSize="20sp" android:text="Name">
</TextView>
<TextView android:id="@+id/task_categoty"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Category" android:textSize="12sp">
</TextView>
</LinearLayout>
<TextView android:id="@+id/task_state"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="State" android:textSize="12sp">
</TextView>
<CheckBox android:id="@+id/task_enabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:focusable="false">
</CheckBox>
</TableRow>
任务都存储在SQLite数据库。我有DAO对象(单身)来访问数据库。TaskDao:
Tasks are stored in SQLite database. I have DAO object (singleton) to access the database.TaskDao:
public void updateEnabled(int id, boolean enabled){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(ENABLED_COLUMN, enabled==true?1:0);
Log.i(TAG, "update to " + cv.get(ENABLED_COLUMN) );
try{
db.beginTransaction();
db.update(TASK_TABLE, cv, ID_COLUMN+"=?", new String[]{id+""});
db.setTransactionSuccessful();
} catch (SQLException e) {
Log.i(TAG, "edit task failed!");
} finally {
db.endTransaction();
if (db != null)
db.close();
}
}
和光标的方法ListActivity:
and the Cursor method for ListActivity:
public Cursor getTasks(){
SQLiteDatabase db = dbHelper.getReadableDatabase();
return db.query(TASK_TABLE, COLUMNS, null, null, null, null, NAME_COLUMN);
}
我伸出SimpleCursorAdapter(TaskDbAdapter)是这样的:
I extended SimpleCursorAdapter (TaskDbAdapter) like this:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
convertView = inflater.inflate(R.layout.task_list_row, null);
}
Cursor c = getCursor();
c.moveToPosition(position);
Log.i(TAG, "getView " + position + " = " + c.getInt(enabledIdx));
enabled.setTag(c.getInt(c.getColumnIndex(BaseColumns._ID)));
enabled.setChecked(c.getInt(enabledIdx)>0?true:false);
enabled.setOnClickListener(this);
return convertView;
}
@Override
public void onClick(View v) {
CheckBox box = (CheckBox) v;
Integer id = (Integer)box.getTag();
TaskDao.getInstance(context).updateEnabled(id.intValue(), box.isChecked());
}
,最后我用上述所有的东西在我的主ListActivity
And at last I use all the above stuff in my main ListActivity
private void refreshList(){
c = TaskDao.getInstance(this).getTasks();
startManagingCursor(c);
adapter = new TaskDbAdapter(this, R.layout.task_list_row, c, new String[]{TaskDao.ENABLED_COLUMN}, new int[]{R.id.task_enabled});
setListAdapter(adapter);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task);
getListView().setItemsCanFocus(false);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
getListView().setVerticalScrollBarEnabled(true);
registerForContextMenu(getListView());
getListView().setOnCreateContextMenuListener(this);
refreshList();
}
@Override
protected void onResume() {
super.onResume();
refreshList();
}
@Override
protected void onPause() {
super.onPause();
}
一切工作正常。但复选框失去它们的状态。比如我检查我的第一列滚动列表了。在我之前,preSS跟踪我有:
Everything works fine. But CheckBoxes loose their states. For instance I check my first column and scroll the list down. In my trace before press I have:
getView 0 = 0
getView 2 = 0
getView 3 = 0
然后
uptate to 1
,然后(当我向上滚动到第一个元素)
and then (when I scroll up to the first element)
getView 0 = 0
getView 2 = 0
getView 3 = 0
我试图让 getCursor()重新查询(); 在我TaskDbAdapter的onClick方法。但后来我看到在列表中没有的项目!例外,因为游标的管理和(连接被关闭机器人)。当我写的 startManagingCursor(C); 在refreshList()方法,然后检查并取消方法不起作用。请帮助!
I tried to make getCursor().requery(); in my TaskDbAdapter onClick method. But then I saw no items in the list! And exception because of cursor management(connection was closed by android). When I write startManagingCursor(c); in refreshList() method then check and uncheck methods don't work.Please, Help!
推荐答案
我有这个问题,以及挣扎。我结束了存储在数据库中的所有检查框为0或1。然后我检查自己的状态,从数据库,以确定他们是否被标记与否。
I struggled with this as well. I ended up storing all checked boxes in the db as either 0 or 1. Then I check their state from the database to determine if they are marked or not.
公共类DetailCursorAdapter扩展SimpleCursorAdapter {
public class DetailCursorAdapter extends SimpleCursorAdapter {
private Cursor c;
private Context context;
public DetailCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
}
public View getView(int pos, View inView, ViewGroup parent) {
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.check_list, null);
}
Log.i("pos = ..................", "pos = "+pos);
this.c.moveToPosition(pos);
//this.c.moveToPosition(this.c.getInt(this.c.getColumnIndex("_id")));
CheckBox cBox = (CheckBox) v.findViewById(R.id.bcheck);
cBox.setTag(this.c.getInt(this.c.getColumnIndex("_id")));
/*
* when reloading the list, check for chkd status, this is broken. Need to query db directly.
*/
EventDbAdapter mDbHelper = new EventDbAdapter(context);
mDbHelper.open();
int idTag = (Integer) cBox.getTag();
int checked = mDbHelper.selectChk(idTag);
mDbHelper.close();
Log.i("results from selectChk.....................", ""+checked);
if (checked == 1) {
cBox.setChecked(true);
} else {
cBox.setChecked(false);
}
/*
* Populate the list
*/
TextView txtdateTime = (TextView)v.findViewById(R.id.time);
txtdateTime.setText(this.c.getString(this.c.getColumnIndex("time")));
TextView txtdateEvent = (TextView)v.findViewById(R.id.event);
txtdateEvent.setText(this.c.getString(this.c.getColumnIndex("event")));
TextView txtdateLocation = (TextView)v.findViewById(R.id.location);
txtdateLocation.setText(this.c.getString(this.c.getColumnIndex("location")));
ImageView arrow = (ImageView) v.findViewById(R.id.arrowId);
arrow.setImageResource(R.drawable.rightarrow);
Log.i("if chk in db is = 1 then set checked.........",this.c.getString(this.c.getColumnIndex("checked")) +" " +this.c.getString(this.c.getColumnIndex("time")));
/*
* Controls action based on clicked list item (background)
*/
View lv = v.getRootView();
lv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View lv) {
CheckBox cBox = (CheckBox) lv.findViewById(R.id.bcheck);
// id holds the rowid of each event. pass this to a new activity to query for description
// Call Event Detail
String id = cBox.getTag().toString();
Intent i = new Intent(context, EventDetail.class);
//i.putExtra("description", c.getString(c.getColumnIndex("description")));
i.putExtra("_id", id);
context.startActivity(i);
}
});
/*
* Begin - Controls action based on clicked Text only
txtdateEvent.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
CharSequence charseq = "Darth Vader is alive";
Toast.makeText(context, charseq, Toast.LENGTH_SHORT).show();
}
});
* End - Controls action based on clicked Text only
*/
/*
* Controls action based on clicked checkbox
*/
cBox.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
EventDbAdapter mDbHelper = new EventDbAdapter(context);
mDbHelper.open();
CheckBox cBox = (CheckBox) v.findViewById(R.id.bcheck);
if (cBox.isChecked()) {
//cBox.setChecked(false);
CharSequence charseq = "Added to My Schedule";
Toast.makeText(context, charseq, Toast.LENGTH_SHORT).show();
// Update the database for each checked item
mDbHelper.updateChecked(cBox.getTag().toString(), "1");
c.requery();
// Verify that the db was updated for debugging purposes
String event = c.getString(c.getColumnIndex("event"));
int id = (Integer) cBox.getTag();
Log.i("checked _id...........", "id= " + id + " " +c.getString(c.getColumnIndex("_id")));
Log.i("checked checked...........", ""+c.getString(c.getColumnIndex("checked")));
} else if (!cBox.isChecked()) {
//cBox.setChecked(true);
CharSequence charseq = "Removed from My Schedule";
Toast.makeText(context, charseq, Toast.LENGTH_SHORT).show();
// checkList.remove(cBox.getTag());
//checkList.add((Integer) cBox.getTag());
String event = c.getString(c.getColumnIndex("event"));
//int id = c.getInt(c.getColumnIndex("_id"));
int id = (Integer) cBox.getTag();
mDbHelper.updateChecked(cBox.getTag().toString(), "0");
c.requery();
//int sqlresult = mDbHelper.selectChk(id, event);
//Log.i("sqlresult checked value after update...........", ""+ sqlresult);
//Log.i("unchecked _id...........", ""+c.getString(c.getColumnIndex("_id")));
//Log.i("unchecked checked...........", ""+c.getString(c.getColumnIndex("checked")));
}
//mDbHelper.close();
}
});
return(v);
}
}
这篇关于安卓:SimpleCursorAdapter使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!