我有一个自定义列表视图,每行包含一个复选框和文本。现在我想要的是如果任何一个listview行的复选框被选中,那么其他行中的其他复选框如果被选中.it将被自动选择。(即一次只能选择一个复选框)。我应该怎么做。< / p>
到目前为止,我所做的工作如下:
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 :(得分:10)
您需要相应地跟踪所选项目和代码。
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;
}
}
答案 1 :(得分:5)
尝试更改所有项目布尔值false在通知适配器后排除选定项目,并为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;
}
答案 2 :(得分:1)
维护变量:
int checked = -1; //say
每当你尝试检查一个复选框时,你检查这个变量,如果它是-1然后检查复选框并保存列表项的位置在已检查变量中,当你试图再次检查其他复选框时,如果变量ain&# 39; t等于-1,首先取消选中已检查变量中存储的位置的复选框,然后选中当前位置的复选框并将当前位置保存在已检查变量中
答案 3 :(得分: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;
}
答案 4 :(得分: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()
完成。希望这会有所帮助。
答案 5 :(得分:1)
使用 getView (与发布的大多数答案一样)对我来说无法正常工作。它没有足够的响应。有时它会取消选中上一个复选框,有时不会。
这对我很有用:
首先,我们需要存储所有先前检查过的复选框的位置:
Set<Integer> selectedPreviousPositions = new HashSet<>();
然后在onItemClick侦听器中,我们取消选中所有复选框,然后再选中我们选中的那个。
@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));
}
}
答案 6 :(得分:0)
在适配器内部,为复选框设置OnClickListener()。每当单击复选框时,都存储单击的复选框位置并调用notifyDataSetChanged()。对于列表视图中的所有视图,将再次使用getView()方法。每当调用getView()时,都将选中先前存储的位置的复选框,然后取消选中其余复选框。
public class CustomAdapter extends ArrayAdapter<YourModelObject>
{
private int selectedCheckBoxPosition = -1;
public int getSelectedCheckBoxPosition()
{
return selectedCheckBoxPosition;
}
@Override
public View getView(final int position, View convertView, final ViewGroup parent)
{
final ViewHolder viewHolder;
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
{
convertView = layoutInflater.inflate(R.layout.list_item, null);
viewHolder = new ViewHolder();
viewHolder.checkBox = (CheckBox) convertView;
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
if (position == selectedCheckBoxPosition)
{
viewHolder.checkBox.setChecked(true);
Log.d(TAG, "checkbox CHECKED at pos: " + position);
}
else
{
viewHolder.checkBox.setChecked(false);
Log.d(TAG, "checkbox UNCHECKED at pos: " + position);
}
//viewHolder.checkBox.setText("sample text");
viewHolder.checkBox.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view) {
selectedCheckBoxPosition = position;
Log.d(TAG, "onClick() - set selectedCheckBoxPosition = " + position);
notifyDataSetChanged();
}
});
return convertView;
}
private class ViewHolder
{
CheckBox checkBox;
}
}