2011-01-28 4 views
1

SimpleCursorAdapter에 하나의 성가신 문제가 있습니다. 내 programm 목록보기 및 ListActivity 있습니다.안드로이드 : SimpleCursorAdapter 용도

<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 :

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에 대한 커서 방법 :이 같은 SimpleCursorAdapter (TaskDbAdapter) 확장

public Cursor getTasks(){ 
    SQLiteDatabase db = dbHelper.getReadableDatabase(); 
    return db.query(TASK_TABLE, COLUMNS, null, null, null, null, NAME_COLUMN); 
} 

:

@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()); 
} 

을 그리고 마지막에 내가에 위의 모든 재료를 사용 내 주요 동작 범위

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(); 

} 

모두 정상적으로 작동합니다. 하지만 CheckBoxes는 상태가 느슨합니다. 예를 들어 첫 번째 열을 확인하고 목록을 아래로 스크롤합니다. 를 눌러 이전에 내 추적에서 내가 가진 : 다음

getView 0 = 0 
getView 2 = 0 
getView 3 = 0 

uptate to 1 

다음

하고 (필자는 첫 번째 요소까지 스크롤 할 때)

getView 0 = 0 
getView 2 = 0 
getView 3 = 0 

내가 getCursor을 만들려고() .requery(); 내 TaskDbAdapter onClick 메서드입니다. 그런데 목록에 항목이 없습니다. 그리고 커서 관리 때문에 예외 (연결은 안드로이드에 의해 닫혔다). 내가 쓸 때 startManagingCursor (c); refreshList() 메서드에서을 선택한 다음 메서드가 작동하지 않는지 확인하고 선택 취소합니다. 제발 도와주세요!

답변

1

내 제안을 완전히 읽지 못 했으므로 제안이 완전히 잘못되었을 수도 있지만 시도해 보겠습니다.

BaseAdapter 클래스의 설명서를 살펴보십시오.

public void notifyDataSetChanged() 

이 작업을 수행 할 수 있습니다.

당신은이에 대한 관찰자를 등록 할 수 있습니다 ...

public void registerDataSetObserver (DataSetObserver observer) 
+0

이 notifyDataSetChanged()를 시도 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); } 

}을 확장 ... 운이 – Nick

1

은 나뿐만 아니라이 고생. 나는 0 또는 1로 db에있는 모든 체크 박스를 저장하는 것을 끝내었다. 그런 다음 데이터베이스에서 상태를 체크하여 표시 여부를 결정했다.

공용 클래스 DetailCursorAdapter이

+0

는 이미 트릭은하지 않았다! (같은 방식으로 :))) – Nick