2013-07-25 112 views
1

美好的一天。ListView中的複選框多選

我有一個列表視圖與每個textview附近的複選框。當我檢查一個複選框並向下滾動時,隨機的其他複選框也會被檢查。我讀過這個post和其他幾個人,他們都說每個複選框的狀態需要保存在getView()的布爾列表中。我會怎麼做呢?

謝謝。

編輯的代碼:

這是適配器的還含有getView()方法的代碼。

public class MyCustomAdapter extends BaseAdapter 
{ 
    public ArrayList<Error> list; 
    private Context mContext; 
    private LayoutInflater mInflator; 

    public MyCustomAdapter(Context context, int textViewResourceId, ArrayList<Error> list) 
    { 
     this.list = list; 
     this.mContext = context; 
     mInflator = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

@Override 
public int getCount() 
{ 
    return list.size(); 
} 

@Override 
public Error getItem(int position) 
{ 
    return list.get(position); 
} 

@Override 
public long getItemId(int position) 
{ 
    return 0; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) 
{ 
    ViewHolder holder; 

    if(convertView == null) 
    { 
     holder = new ViewHolder(); 

     convertView = mInflator.inflate(R.layout.listviewrow, null); 

     holder.text = (TextView)convertView.findViewById(R.id.text); 
     holder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox); 

     convertView.setTag(holder); 
    } 
    else 
    { 
     holder = (ViewHolder)convertView.getTag(); 
    } 

    final int pos = position; 
    holder.text.setText(list.get(position).getDescription()); 
    holder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() 
    { 

     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
     { 
      list.get(pos).setChecked(isChecked); 
     } 
    }); 

    return convertView; 
} 

static class ViewHolder 
{ 
    TextView text; 
    CheckBox checkbox; 
} 



} 

回答

9

下面的代碼爲我工作

我mainActivity

public class MainActivity extends Activity { 

    private ListView llChb; 

    private String[] data = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", 
      "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", 
      "x", "y", "z" }; 
    private ArrayList<String> arrData=null; 

    private ArrayList<InfoRowdata> infodata; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     arrData=new ArrayList<String>(); 
     arrData.add("a"); 
     arrData.add("b"); 
     arrData.add("c"); 
     arrData.add("d"); 
     arrData.add("e"); 
     arrData.add("f"); 
     arrData.add("g"); 
     arrData.add("h"); 
     arrData.add("i"); 
     arrData.add("j"); 
     arrData.add("k"); 
     arrData.add("l"); 
     arrData.add("m"); 
     arrData.add("n"); 
     arrData.add("o"); 
     arrData.add("p"); 
     llChb = (ListView) findViewById(R.id.llChb); 

     infodata = new ArrayList<InfoRowdata>(); 
     for (int i = 0; i < data.length; i++) { 
      infodata.add(new InfoRowdata(false, i)); 
      // System.out.println(i); 
      //System.out.println("Data is == "+data[i]); 
     } 
     llChb.invalidate(); 
     llChb.setAdapter(new MyAdapter()); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.activity_main, menu); 
     return true; 
    } 

    public class MyAdapter extends BaseAdapter { 

     @Override 
     public int getCount() { 
      // TODO Auto-generated method stub 
      return data.length; 
     } 

     @Override 
     public Object getItem(int position) { 
      // TODO Auto-generated method stub 
      return null; 
     } 

     @Override 
     public long getItemId(int position) { 
      // TODO Auto-generated method stub 
      return 0; 
     } 

     @Override 
     public View getView(final int position, View convertView, ViewGroup parent) { 
      // TODO Auto-generated method stub 
      View row = null; 
      row = View.inflate(getApplicationContext(), R.layout.row, null); 
      TextView tvContent=(TextView) row.findViewById(R.id.tvContent); 
      //tvContent.setText(data[position]); 
      tvContent.setText(data[position]); 
      //System.out.println("The Text is here like.. == "+tvContent.getText().toString()); 

      final CheckBox cb = (CheckBox) row 
        .findViewById(R.id.chbContent); 
      cb.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        // TODO Auto-generated method stub 
        if (infodata.get(position).isclicked) { 
          infodata.get(position).isclicked = false; 
         } else { 
          infodata.get(position).isclicked = true; 
         } 

        for(int i=0;i<infodata.size();i++) 
        { 
         if (infodata.get(i).isclicked) 
         { 
          System.out.println("Selectes Are == "+ data[i]); 
         } 
        } 
       } 
      }); 

      if (infodata.get(position).isclicked) { 

       cb.setChecked(true); 
      } 
      else { 
       cb.setChecked(false); 
      } 
      return row; 
     } 

    } 
} 

我InfoRowdata模型類

public class InfoRowdata { 

    public boolean isclicked=false; 
    public int index; 
    /*public String fanId; 
    public String strAmount;*/ 

    public InfoRowdata(boolean isclicked,int index/*,String fanId,String strAmount*/) 
    { 
     this.index=index; 
     this.isclicked=isclicked; 
     /*this.fanId=fanId; 
     this.strAmount=strAmount;*/ 
    } 

} 

我MainXml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".MainActivity" > 

    <ListView 
     android:id="@+id/llChb" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" > 
    </ListView> 

</RelativeLayout> 

這是清單定製RowXml查看

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/rlMain" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 

     <RelativeLayout 
      android:id="@+id/rlInner" 
      android:layout_width="fill_parent" 
      android:layout_height="50dp" > 

      <TextView 
       android:id="@+id/tvContent" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_centerVertical="true" 
       android:layout_marginLeft="20dp" 
       android:text="Medium Text" 
       android:textColor="#000000" /> 

      <CheckBox 
       android:id="@+id/chbContent" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_alignParentRight="true" 
       android:layout_centerVertical="true" 
       android:layout_marginRight="10dp" /> 

     </RelativeLayout> 

    </RelativeLayout> 
+0

嗨Saurabh,謝謝你張貼工作代碼。我正在使用'checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener)'而不是'onClickListener'。它的工作原理是否一樣? – ClaireG

+1

是的,這將比你需要維護同一段代碼以及此方法的布爾參數 –

+0

@ClaireGatt讓你的問題得到解決或不。 –

3

listView中的視圖被回收,這意味着當一個視圖離開屏幕時,它將被重新用於下一個視圖的出現。 這也意味着,如果你沒有設置複選框到你想要的任何狀態,它將保持從回收視圖的狀態。

你使用什麼樣的適配器?

+0

我爲此創建了一個自定義適配器。 – ClaireG

+0

因此,在getView方法中,一定要用true或false爲項目實現cb.setChecked()。 – Zoubiock

+0

試過了,他們仍在檢查。 – ClaireG

0

使用此

 ViewHolder holder; 
     holder = new ViewHolder(); 

     convertView = mInflator.inflate(R.layout.listviewrow, null); 

     holder.text = (TextView)convertView.findViewById(R.id.text); 
     holder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox); 

     convertView.setTag(holder); 

而不是

ViewHolder holder; 

    if(convertView == null) 
    { 
     holder = new ViewHolder(); 

     convertView = mInflator.inflate(R.layout.listviewrow, null); 

     holder.text = (TextView)convertView.findViewById(R.id.text); 
     holder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox); 

     convertView.setTag(holder); 
    } 
    else 
    { 
     holder = (ViewHolder)convertView.getTag(); 
    } 

我面臨同樣的問題。可能是你會得到答案!

+0

我可以但我有一個佈局,我用它來填充列表視圖中的每一行。 – ClaireG

-1

如果你仍然在這裏尋找答案,它會發生。有些人在stackoverflow中評論說,如果我們使用自定義適配器或自定義ListView,那麼我們必須記住複選框的狀態。但是不需要記住。 ListView會記住它。所以在實施之前請理解下面的項目。

  1. 什麼是ListView和適配器。
  2. 適配器如何調用getView並更新listView中的每個項目。
  3. 當我們向上/向下滾動時(在listview中的某些項目將被隱藏,即getView將返回什麼)會發生什麼。
  4. 瀏覽ListView API。這很重要。

一旦你瞭解了上面提到的幾點,那麼回答很簡單。 ListView將記住所有的狀態,並可以通過傳遞位置作爲參數使用isItemChecked進行提取。