2014-11-24 30 views
7

我有一个自定义列表视图,每行都包含一个复选框和文本。现在我想要的是,如果任何一个listview行的复选框被选中,所以其他行中的其他行复选框会被自动选中(即一次只能选择一个复选框)。我应该怎么做。只有一个复选框的自定义列表视图被一次选中一个

到目前为止,我所做的是:

public class CustomAdapter extends BaseAdapter{ 

    Context context; 
    List<String> items; 

    boolean array[]; 


    public CustomAdapter(Context context, List<String> items) { 
    super(); 
    this.context = context; 
    this.items = items; 
    array =new boolean[items.size()]; 
} 


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

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

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

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     // TODO Auto-generated method stub 
     View v=convertView; 
     final int pos=position; 
     if(v==null) 
     { 
      v=LayoutInflater.from(context).inflate(R.layout.list,null); 
     } 

     TextView txt1=(TextView) v.findViewById(R.id.textView1); 
     final CheckBox chkbox=(CheckBox) v.findViewById(R.id.checkBox1); 

     txt1.setText(items.get(position)); 
     int selectedindexitem=0; 
     chkbox.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       if(chkbox.isChecked()) 
       { 
        array[pos]=true; 


       }else{ 
        array[pos]=false; 
       } 
      } 
     }); 
     chkbox.setChecked(array[pos]); 





     return v; 
    } 




} 

In this code i can select multiple checkbox at a time but i need only one checkbox should be checked one at a time. 
+0

由于您在视图中使用复选框而不是在listview中使用复选框,因此应手动取消选中它们。为此,你需要保留一个你已经选择的参考,而不是。 – 2014-11-24 12:49:54

+0

一个非常简单的方法就是用RadioButton替换你的CheckBox,并确保所有的RadioButton都在同一个RadioGroup中。 – 2014-11-24 13:14:25

+0

我不能使用radiogroup – abh22ishek 2014-11-24 13:19:02

回答

12

您需要相应地跟踪所选项目和代码。

public class CustomAdapter extends BaseAdapter{ 
    Integer selected_position = -1; 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
      // Your Code 

      chkbox.setChecked(position==selected_position); 

      chkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

       @Override 
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
        if(isChecked) 
        { 
         selected_position = position; 
        } 
        else{ 
         selected_position = -1; 
        } 
        notifyDataSetChanged(); 
       } 
      }); 
      return convertView; 


     } 
} 
+0

我需要使用setonCheckedChangeListner,我不能使用onclick ?? – abh22ishek 2014-11-24 12:56:52

+0

然后选择另一个复选框。我需要重新加载整个列表视图? – abh22ishek 2014-11-24 13:00:03

+0

[setonCheckedChangeListner](http://developer.android.com/reference/android/widget/CompoundButton.OnCheckedChangeListener.html)被调用时复选按钮的检查状态发生了变化,CheckBox – 2014-11-24 13:01:03

1

维持一个变量:

int checked = -1; //say 

每当你尝试检查一个复选框选中此变量,如果是-1,那么选中复选框并将列表项的位置保存在checked变量中,当您尝试再次选中其他复选框时,如果该变量不等于-1,则首先取消选中存储在checked变量中的位置上的复选框,然后选中当前位置的复选框并保存当前位置i n已检查变量

4

试图改变错误的排除选定的项目通知适配器后,还实施ListView的性能ViewHolder设计模式,所有项目的布尔值:

@Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 
     if(convertView==null){ 
      holder = new ViewHolder(); 
      convertView = LayoutInflater.from(context).inflate(R.layout.list,null); 
      holder.txt1 = (TextView) convertView.findViewById(R.id.textView1); 
      holder.chkbox = (CheckBox) convertView.findViewById(R.id.checkBox1); 
      convertView.setTag(holder); 
     }else{ 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     holder.txt1.setText(items.get(position)); 
     holder.chkbox.setChecked(array[position]); 
     holder.chkbox.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       for (int i=0;i<array.length;i++){ 
        if(i==position){ 
         array[i]=true; 
        }else{ 
         array[i]=false; 
        } 
       } 
       notifyDataSetChanged(); 
      } 
     }); 

     return convertView; 
    } 

    class ViewHolder{ 
     TextView txt1; 
     CheckBox chkbox; 
    } 
1
@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     // TODO Auto-generated method stub 
     View v=convertView; 
     final int pos=position; 
     if(v==null) 
     { 
      v=LayoutInflater.from(context).inflate(R.layout.list,null); 
     } 

     TextView txt1=(TextView) v.findViewById(R.id.textView1); 
     final CheckBox chkbox=(CheckBox) v.findViewById(R.id.checkBox1); 

     txt1.setText(items.get(position)); 
     int selectedindexitem=0; 

     if(position==selected_position) 
     { 
      chkbox.setChecked(true); 
     } 
     else 
     { 
      chkbox.setChecked(false); 
     } 
     chkbox.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       if(chkbox.isChecked()) 
       { 
        array[pos]=true; 
        selected_position = pos; 
       }else{ 
        array[pos]=false; 
       } 
      } 
     }); 
     chkbox.setChecked(array[pos]); 
     MainActivity.lv.setAdapter(new CustomAdapter(context,MainActivity.listitems)); 




     return v; 
    } 
+0

@SweetWisherツ因为我已经这样做 - 但这是行不通的 – abh22ishek 2014-11-24 13:27:23

+0

write notifyDataSetChanged();在'setOnClickListener'中 – 2014-11-25 08:42:41

1

易于维护您的选择。从模型中获取您的选择。

class PropertyModel{ 
String VAL= "SOME VALUE" 
boolean selected = false; 

public String getVAL() {return VAL;} 
public void setVAL(String VAL) {this.VAL = VAL;} 
public boolean isSelected() {return selected;} 
public void setSelected(boolean selected) {this.selected = selected;} 
} 

准备好您的看法是这样的:

public class CheckBoxAdptr extends BaseAdapter{ 
    /*  
    .......... 
    */ 

    public View getView(int position, View view, ViewGroup parent) { 
    PropertyModel items = list.get(position); 
    View row; 
    if (view == null) { 
     LayoutInflater inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     row = inflater.inflate(R.layout.list_item_checkbox, null); 
    } 
    else{row = view;} 

    TextView T1 = (TextView) row.findViewById(R.id.list_item_1); 
    CheckBox checkBox = (CheckBox) row.findViewById(R.id.list_item_check_box); 

    T1.setText(""+items.getVAL()); 
    if(items.isSelected()){ 
     checkBox.setChecked(true); 
    } 
    else {checkBox.setChecked(false);} 

    return row; 
} 
} 
在活动或片段设置适配器

现在做这样的事情:

final ArrayList<PropertyModel> list = getList(); 
    CheckBoxAdptr adpt = new CheckBoxAdptr(getActivity(), list); 
    listview.setAdapter(adpt); 

    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { 
      for(int i = 0; i<list.size(); i++){ 
       if(i!=position){ 
        list.get(i).setSelected(false); 
       } 
       else{ 
        list.get(i).setSelected(true); 
       } 
      } 
      adpt.notifyDataSetChanged(); 
     } 
    }); 

注意,所有的工作都是由做adpt.notifyDataSetChanged()。希望这可以帮助。

1

使用getView(如发布的大多数答案)对我来说工作不正常。它没有足够的反应。有时它会取消选中前一个复选框,有时不选。

这完美地工作对我来说:

首先,我们需要存储所有先前选中的复选框的位置:然后在onItemClick听众

Set<Integer> selectedPreviousPositions = new HashSet<>(); 

我们检查一个我们之前取消所有复选框选择。

@Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     boolean isChecked = ((CheckBox) view.findViewById(R.id.cbSelected)).isChecked(); 
     if (!isChecked) { 
      final ListView listDevices = (ListView) findViewById(R.id.lvDevices); 
      for (Integer pos : selectedPreviousPositions) { 
       View pView = listDevices.getChildAt(pos); 
       if (pView != null) { // unnecessary but we never know ! 
        ((CheckBox)pView.findViewById(R.id.checkboxID)).setChecked(false); 
       } 
      } 
      selectedUniquePositions.add(new Integer(position)); 
      // Now we can check the selected checkbox 
      ((CheckBox) view.findViewById(R.id.cbSelected)).setChecked(true); 
     } else { 
      ((CheckBox) view.findViewById(R.id.cbSelected)).setChecked(false); 
      selectedPreviousPositions.remove(new Integer(position)); 

     } 
    } 
相关问题