2012-04-15 88 views
4

我正在使用自定義的ResourceCursorAdapter來顯示TextView和CheckBox的ListView。 TextView和CheckBox從Cursor獲取它們的狀態。我一直在遇到一些問題,最近的一個問題是,當我滾動一些行時,會從舊的TextView中獲取文本,而當它們不應該被選中時,會選中一些CheckBox。我已經添加了一個日誌行來看看發生了什麼,這只是讓我更困惑。如何防止再生的ListView項目顯示舊內容?

@Override 
public void bindView(View v, Context ctx, Cursor c) { 
    ViewHolder holder = (ViewHolder)v.getTag(); 

holder.tv.setText(holder.tvText);   
holder.cb.setChecked(holder.checked); 
Log.d(TAG, "in bindView, rowId:" + holder.rowId + " Scripture:" + holder.tvText); 
} 

@Override 
public View newView(Context ctx, Cursor c, ViewGroup vg){  

    View v = li.inflate(layout, vg, false); 
    ViewHolder holder; 

    holder = new ViewHolder(); 
    holder.tv = (TextView)v.findViewById(to[0]); 
    holder.tvText = c.getString(c.getColumnIndex(from[0])); 
    holder.cb = (CheckBox)v.findViewById(to[1]); 
    holder.rowId = c.getLong(c.getColumnIndex(from[2])); 
    holder.checked = (c.getString(c.getColumnIndexOrThrow(from[1])).equals("n")) ? 
      false : true; 
    holder.cb.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      View rowView = ((View)v.getParent()); 
      ViewHolder holder = (ViewHolder)rowView.getTag(); 

      holder.checked = (holder.checked == false) ? true : false; 

      smDb.setMemorized(holder.rowId); 
      rowView.setTag(holder); 
      Log.d(TAG, "check box clicked: " + holder.rowId); 
     }}); 
    Log.d(TAG, "in newView, rowId:" + holder.rowId); 
    v.setTag(holder); 


    return v;  
} 

static class ViewHolder { 
    TextView tv; 
    String tvText; 
    CheckBox cb; 
    boolean checked; 
    Long rowId; 
} 

日誌輸出

in newView, rowId:26 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in newView, rowId:27 
in bindView, rowId:27 Scripture:Matthew 6:24 
in newView, rowId:28 
in bindView, rowId:28 Scripture:Matthew 16:15-9 
in newView, rowId:29 
in bindView, rowId:29 Scripture:Matthew 25:40 
in newView, rowId:30 
in bindView, rowId:30 Scripture:Luke 24:36-9 
in newView, rowId:31 
in bindView, rowId:31 Scripture:John 3:5 
in newView, rowId:32 
in bindView, rowId:32 Scripture:John 7:17 
in newView, rowId:33 
in bindView, rowId:33 Scripture:John 10:16 
in newView, rowId:34 
in bindView, rowId:34 Scripture:John 14:15 
in newView, rowId:26 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 
in bindView, rowId:26 Scripture:Matthew 5:14-6 

回答

0

這是造成您的問題的看法回收。

我不確定這是處理它的最流暢的方式,但這是我做到的。我做了一個數組來保存我的按鈕狀態信息,然後在我的getView方法中使用它,以確保即使元素不在屏幕上時狀態也會保持不變。

從我的項目,我必須在每個排按鈕的列表適配器的一個

例子,可以有幾個州(文本和彩色):

public class ButtonCursorAdapter extends SimpleCursorAdapter { 
    private Cursor c;      // Passed in cursor 
    private Context context; 
    private Activity activity; 
    public static String[] atdState;  // String array to hold button state 
    public static String[] atdRow;   // Matching string array to hold db rowId 

    public ButtonCursorAdapter(Context context, int layout, Cursor c, 
        String[] from, int[] to) { 
      super(context, layout, c, from, to); 
      this.c = c; 
      this.context = context; 
      this.activity = (Activity) context; 
      atdState = new String[c.getCount()]; // initialize button state array 
      atdRow = new String[c.getCount()]; // initialize db rowId array 
      c.moveToFirst(); 
      int i = 0; 
      while (c.isAfterLast() == false) { 
        if (c.getString(3) == null) { // if state is null, set to " " 
          atdState[i] = " "; 
        } else { 
          atdState[i] = c.getString(3); // set state to state saved in db 
        } 
        atdRow[i] = c.getString(0);  // set the rowId from the db 
        i++; 
        c.moveToNext(); 
      } 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
      if (convertView == null) 
        convertView = View.inflate(context, 
            R.layout.listlayoutdoublebutton, null); 
      final int pos = position; 
      View row = convertView; 
      c.moveToPosition(position); 
      TextView first = (TextView) convertView.findViewById(R.id.ListItem1); 
      TextView last = (TextView) convertView.findViewById(R.id.ListItem2); 
      Button atdButton = (Button) convertView.findViewById(R.id.attendbutton); 
      first.setText(c.getString(1)); 
      last.setText(c.getString(2)); 
      atdButton.setText(atdState[position]); // set the button state 
      if (atdState[position].equals("P")) { // colorize the button depending on state 
        atdButton.getBackground().setColorFilter(0xFF00FF00, 
            PorterDuff.Mode.MULTIPLY); 
      } else if (atdState[position].equals("T")) { 
        atdButton.getBackground().setColorFilter(0xFFFFFF00, 
            PorterDuff.Mode.MULTIPLY); 
      } else if (atdState[position].equals("E")) { 
        atdButton.getBackground().setColorFilter(0xFFFF6600, 
            PorterDuff.Mode.MULTIPLY); 
      } else if (atdState[position].equals("U")) { 
        atdButton.getBackground().setColorFilter(0xFFFF0000, 
            PorterDuff.Mode.MULTIPLY); 
      } else { 
        atdButton.getBackground().clearColorFilter(); 
      } 
      atdButton.setFocusable(true); 
      atdButton.setClickable(true); 

      atdButton.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View view) { 
          Button atdButton = (Button) view 
              .findViewById(R.id.attendbutton); 
          String test = atdButton.getText().toString(); 
          if (test.equals(" ")) { 
            atdButton.setText("P"); 
            atdState[pos] = "P"; 
            atdButton.getBackground().setColorFilter(0xFF00FF00, 
                PorterDuff.Mode.MULTIPLY); 
          } else if (test.equals("P")) { 
            atdButton.setText("T"); 
            atdState[pos] = "T"; 
            atdButton.getBackground().setColorFilter(0xFFFFFF00, 
                PorterDuff.Mode.MULTIPLY); 
          } else if (test.equals("T")) { 
            atdButton.setText("E"); 
            atdState[pos] = "E"; 
            atdButton.getBackground().setColorFilter(0xFFFF6600, 
                PorterDuff.Mode.MULTIPLY); 
          } else if (test.equals("E")) { 
            atdButton.setText("U"); 
            atdState[pos] = "U"; 
            atdButton.getBackground().setColorFilter(0xFFFF0000, 
                PorterDuff.Mode.MULTIPLY); 
          } else if (test.equals("U")) { 
            atdButton.setText("P"); 
            atdState[pos] = "P"; 
            atdButton.getBackground().setColorFilter(0xFF00FF00, 
                PorterDuff.Mode.MULTIPLY); 
          } 
        } 
      }); 
      return (row); 
    } 

}

當我使用的setText和着色我的按鈕,你想setChecked或一些這樣的,但希望這會指出你在正確的方向。

+0

我已經通過將所有ViewHeader代碼投入bindView方法來解決重複項目的問題,這正是我之前所做的。現在我回到之前的一個問題,當我點擊一個複選框時,屏幕和數據庫中的狀態發生了變化,但是當我將它從屏幕上滾動並將其恢復到原始狀態時。有沒有辦法在創建狀態和重繪時設置狀態? (退出活動並返回顯示更改) – 2012-04-15 02:42:13

+0

這是我在答案中顯示的代碼。創建一個數組來保存項目的狀態,並在你的bindView中引用。如果你看看我的代碼,你會看到我基於我的數組而不是直接分配按鈕文本和顏色。在進行更改時保持陣列更新,每次裝入視圖時都會正確設置狀態。 – Barak 2012-04-15 03:51:50