2011-01-28 77 views
1

我有SimpleCursorAdapter一個煩人的問題。我的程序有列表視圖和ListActivity。每一行都有自己的佈局:Android: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光標方法:

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

我伸出SimpleCursorAdapter(TaskDbAdapter)是這樣的:

@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

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方法。但後來我在列表中看不到任何物品!由於光標管理而異常(連接被android關閉)。當我寫startManagingCursor(c);在refreshList()方法中使用,然後選中並取消選中方法不起作用。 請幫忙!

回答

1

我沒有閱讀你所有的資料,所以我的建議可能是完全錯誤的,但我會試一試。

看看BaseAdapter類的文檔。

public void notifyDataSetChanged() 

可能做的工作。

您也可以爲這個註冊的觀察者......

public void registerDataSetObserver (DataSetObserver observer) 
+0

試圖notifyDataSetChanged()...沒有運氣 – Nick 2011-01-29 16:41:31

1

我這種掙扎也是如此。我最終將所有選中的框存儲在數據庫中,分別爲0或1.然後,我從數據庫中檢查它們的狀態以確定它們是否被標記。

公共類DetailCursorAdapter擴展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); 
} 

}

+0

我已經做的伎倆! (一樣的方法:))) – Nick 2011-04-11 09:09:03