如何使用复选框Android避免ListiView中的重复操作?

时间:2016-10-07 15:48:45

标签: android android-layout listview checkbox

我正在开发一个使用检查清单从车辆通知州的应用程序。

我正在使用带有TextView和两个Checkbox的ListView的Custom Adater。

复选框用于表示特征是否符合修订版。

实际上这个列表有七个项目,但在手机中只显示六个,由于布局大小,问题不在这里。问题是在ListView中重用View,当检查第一个或第二个位置时,当我滚动到它们时,第六个和第七个也被检查,但是TextView的文本显示正确。

我已经阅读了这些问题,但我现在不知道这样做了:

Duplicated entries in ListView

TextView in listview rows showing repeated values on scroll in Android?

List items position repeating in getview

Android Listview row repeating item <--- this question show my problem

The tutorial that I made

The code:

ListAdapter:

public class ListAdapter extends ArrayAdapter<String> {

Context context;
int layoutResourceId;
String data[] = null;
LayoutInflater inflater;
boolean[] cumpleCheckboxState;
boolean[] noCumpleCheckboxState;

public ListAdapter(Context context, int layoutResourceId,
        String[] data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
    cumpleCheckboxState = new boolean[data.length];
    noCumpleCheckboxState = new boolean[data.length];

}

    @Override
public View getView(final int position, final View convertView, ViewGroup parent) {
    View row = convertView;
    final MatrixHolder holder;

    if (row == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);
        holder = new MatrixHolder();
        holder.txtTitle = (TextView) row.findViewById(R.id.headingitem);
        holder.cumpleCheckbox = (CheckBox) row.findViewById(R.id.cumple);
        holder.noCumpleCheckbox = (CheckBox) row.findViewById(R.id.noCumple);
        holder.cumpleCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                Log.e("Position","Nro.: " + position + " " + isChecked);
                cumpleCheckboxState[position] = isChecked;
            }
        });
        holder.noCumpleCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                Log.e("Position","Nro.: " + position + " " + isChecked);
                noCumpleCheckboxState[position] = isChecked;
            }
        });
        row.setTag(holder);
    } else {
        holder = (MatrixHolder) row.getTag();
    }
    for (int i = 0; i < cumpleCheckboxState.length; i++) {
        Log.e("Estados","item: " + i + " Posicion:" + cumpleCheckboxState[i]);
    }
    Log.e("Position","Posicion:" + position);
    holder.txtTitle.setText(data[position]);
    holder.cumpleCheckbox.setChecked(cumpleCheckboxState[position]);
    holder.cumpleCheckbox.setChecked(noCumpleCheckboxState[position]);
    row.setTag(holder);
    return row;
}

static class MatrixHolder {
    TextView txtTitle;
    LinearLayout layout;
    int position;
}

}

添加适配器:

        ListAdapter listAdapter = new ListAdapter(getContext(),R.layout.horizontal_checkbox, itemList);
        final ListView listView2 = (ListView)view.findViewById(R.id.listView);
        listView2.setAdapter(listAdapter);

列表布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
    android:id="@+id/headingitem"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="left"
    android:padding="5dp"
    android:textSize="20dp"/>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/linearmain"
    android:layout_gravity="center_horizontal|center_vertical"
    android:orientation="horizontal" >

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Cumple"
        android:paddingLeft="2sp"
        android:paddingRight="2sp"
        android:layout_weight="1"
        android:id="@+id/cumple"
        />
    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="No Cumple"
        android:paddingLeft="2sp"
        android:paddingRight="2sp"
        android:layout_weight="1"
        android:id="@+id/noCumple"
        />
</LinearLayout>

屏幕

Screenshots

其他问题。如何为这些复选框添加侦听器,并阻止检查行上的两个复选框

欢迎所有的建议或建议

抱歉我的英文不好

编辑:我更新了代码,因为@jereksel说,但是当我向下滚动然后向上看时,我发现布尔值设置为false,是否有任何建议?

3 个答案:

答案 0 :(得分:0)

对于每个复选框,您应该创建一个可以保持其状态的数组:

boolean[] cumpleCheckboxState;
boolean[] noCumpleCheckboxState;

您当然必须在构造函数

中初始化它们
cumpleCheckboxState = new boolean[data.length];
noCumpleCheckboxState = new boolean[data.length];

您还必须将这些cumpleCheckboxnoCumpleCheckbox添加到MatrixHolder

然后你应该在getView中创建一个在复选框被选中时会改变这些数组状态的监听器

holder.cumpleCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView,
                                 boolean isChecked) {
        cumpleCheckboxState[position] = isChecked;
    }
}

noCumpleCheckbox的CheckChangeListener看起来是一样的,只需用cumpleCheckboxState替换noCumpleCheckboxState

我们还必须添加代码(在getView中),它将根据数组在新/重用视图上设置复选框状态。

holder.cumpleCheckbox.setChecked(cumpleCheckboxState[position]);
holder.noCumpleCheckbox.setChecked(noCumpleCheckboxState[position]);

如果您不希望签入两个复选框,则可以禁用一个复选框(在检查第二个复选框时使用setEnabled(false))。

答案 1 :(得分:0)

我可以看到代码中的一些问题和改进。 首先,为什么要在ListAdapter构造函数中保存上下文和layoutResourceId?您通常使用构造函数来存储数据集。

看起来你从来没有在getView中使用或引用你的checkBox,它甚至不是你的MatrixHolder中的属性。

你应该在getView中充气你的单元格视图     row = inflator.inflate(R.layout.horizo​​ntal_checkbox,null) 然后将矩阵持有者复选框设置为     holder.checkBox1 = row.findViewById(your_id); 最后,您可以为每个复选框设置单击侦听器。

只是好奇心?您是否考虑过使用Recyclerview?

希望这会有所帮助。这是一个关于listview的好链接,带有一个复选框。 http://www.mysamplecode.com/2012/07/android-listview-checkbox-example.html

答案 2 :(得分:0)

    @Override
    public int getViewTypeCount() {
        return getCount();
    }
    @Override
    public int getItemViewType(int position) {
        return position;
    }

尝试将其添加到您的 Adapter 类中!它对我有用