【问题标题】:How to avoid duplicated actions in ListiView with checkboxes Android?如何使用复选框 Android 避免 ListView 中的重复操作?
【发布时间】:2016-10-07 15:48:44
【问题描述】:

我正在开发一个应用程序,它使用检查列表来通知车辆的状态。

我正在为 ListView 使用一个自定义 Adater,其中包含一个 TextView 和两个复选框。

复选框用于指示特性是否符合修订。

实际上列表有七个项目但在手机中只显示六个,因为布局大小,问题不在这里。问题是 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:

列表适配器:

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,有什么建议吗?

【问题讨论】:

  • 当活动打开时,所有的复选框都是空的,然后用户将它们用作输入字段,你最后保存了吗?对吗?
  • @Jj 是的,先生,然后我使用这些数据在 Web 服务中做一些工作。实际上,该列表显示在一个片段中。我为此而来,因为客户要求进行此更改,但我使用 CheckedTextView 完成此操作没有问题,但这更复杂。 T_T 问候。
  • 你可以看看我的回答:stackoverflow.com/questions/39926388/…。这应该会有所帮助。

标签: android android-layout listview checkbox


【解决方案1】:

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

您似乎从未在 getView 中使用或引用过您的复选框,而且它甚至不是您的 MatrixHolder 中的属性。

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

只是为了好奇?您是否考虑过使用回收站视图?

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

【讨论】:

    【解决方案2】:

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

    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 中),这些代码将根据 do 数组在新的/重用的视图上设置复选框状态。

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

    如果您不想在一次选中两个复选框,则可以禁用一个(选中第二个时使用setEnabled(false))。

    【讨论】:

    • 我已经按照你说的更新了代码。请查看编辑结果。谢谢
    【解决方案3】:
        @Override
        public int getViewTypeCount() {
            return getCount();
        }
        @Override
        public int getItemViewType(int position) {
            return position;
        }
    

    尝试将它添加到您的适配器类!它对我有用

    【讨论】:

      猜你喜欢
      • 2011-08-30
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 2011-11-11
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多