为了账号安全,请及时绑定邮箱和手机立即绑定

在通过列表视图检查动态生成复选框时获取问题

在通过列表视图检查动态生成复选框时获取问题

人到中年有点甜 2019-06-26 13:54:55
在通过列表视图检查动态生成复选框时获取问题我知道这个问题已经被其他议员问过了,也有一些议员给出了解决办法,但问题是我没有找到适合我的应用程序的解决方案。我正在创建一个应用程序,其中我有一个屏幕,它将显示动态列表视图和列表项,一个复选框和三个文本视图(一个用于候选名称,另两个用于时钟和时钟输出时间,它们将在按日期选择时间选择后显示)。现在,我的问题是,当我选中第一个复选框(我有15个带有复选框的候选人姓名)时,自动第10个复选框检查自己,这也发生在第二、第十一、第三和第十二等(反过来说也是真的)。在这里,我提供我的适配器类和列表项XML。import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Context;import android.util.SparseBooleanArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.TextView;import android.widget.Toast;import com.android.feedback.ListViewCheckBox;public class DemoAdapter extends ArrayAdapter<String>{     private final List<String> list;     private final Activity context;     LayoutInflater inflater;     TextView CItv,COtv;     static ViewHolder holder;     View view;     public DemoAdapter(Activity context, List<String> list) {         super(context, R.layout.test_listitems,list);         // TODO Auto-generated constructor stub         this.context = context;         this.list = list;     }     static class ViewHolder {         protected TextView text,CItv,COtv;         protected CheckBox checkbox;     }请帮助我解决这个问题。(ListViewCheckBox是一个类,它生成列表并将日期和时间的值存储在变量DT_SELECT和OutDT_SELECT中)。
查看完整描述

3 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

下面是回收的实际想法和过程,这样您就可以知道您的实现和想法有什么问题。getView(也许其他人也会发现这个问题和答案)。请参阅下面的代码示例,只需忽略类型部分,因为这是附加信息。

  • 第一阶段:为循环再造而制作的物品(convertViewnull):
    这意味着创建布局和所有项共享的公共状态。如果您有侦听器,您可以在这里添加它们,并设计它们,以便它们能够在以后的位置更改(当它被重用时)作出反应。因此,例如,通过将位置设置为相应视图上的标记,监听器可以捕获该信息,并知道它当前操作的项目。不能使用视图存储数据。因此,当侦听器更改列表项上的状态时,应将此数据持久化(在数据数组中、SQLite数据库中等),并在第二阶段.

  • 第二阶段:设置给定位置的项目状态:
    设置项目的可视状态。对于某一项可能单独更改的所有内容(文本、复选框状态、颜色等)都必须在这里设置。不仅更改了当前项的内容,而且还可能被另一项更改。通过这种方式,可以确保视图不用于无效状态,因为它以前是从另一个列表项中重用的。


被指控的答案被删除/编辑,但建议执行getItemViewTypegetViewTypeCount因此,每个列表项都有自己的视图类型。编辑的答案现在展示了如何用这里描述的方式来解决这个问题。

重新实施getItemViewTypegetViewTypeCount有效,但您显然误解了它的用法(请参阅下面的示例和/或这个答案).

这两种方法用于使用完全不同的两个(或多个)列表项(例如,公共列表项和仅包含标题的分隔符),而不是避免回收可重用的视图。

如果您使用它们来解决您的问题,您可能不理解我之前解释过的过程。例如,您有1000个项,然后执行视图类型黑客然后,您将创建1000个视图(层次结构),而可能会创建10个可重用的视图。容易..如果你只有20件左右的物品,那就没那么重要了,但是如果你把这种技术用于大清单,你只是在浪费(宝贵的)内存!

下面是一个例子:

void getItemViewType(int position) {
    return isItemAtPositionSeperator(position) ? 1 : /* normal item */ 0;}void int getViewTypeCount() {
    return 2; // normal item and separator}void View getView(int position, View convertView, ViewGroup parent) {
    int type = getItemViewType(position);

    // phase 1: see my explanation 
    if (convertView == null) {
        if (type == 0) {
            // setup your common item view - inflate it and set to convertView
        } else {
            // setup separator view - inflate it and set to convertView
        }
    }

    // phase 2: see my explanation 
    if (type == 0) {
        // set the state of the common item view based on the position
        // rely on the fact that convertView contains the view hierarchy
        // you created in convertView == null && type == 0
    } else {
        // set state of the separator based on the position
        // rely on the fact that convertView contains the view hierarchy
        // you created in convertView == null && type != 0 (else part)
    }

    return convertView;}

问题的实际答案.。

我知道问题出在哪里,但我现在想不出一个优雅的解决方案.

您的问题是将单击侦听器设置为viewHolder.checkbox.setOnCheckedChangeListener创建视图时。因此,当您滚动并且单击行为应用于错误的列表项时,它将被回收/重用。

尽量不要硬码使用外部的位置final position..尝试设置viewHolder.checkbox.setTag(position)以前return然后使用(Integer) buttonView.getTag()相反position+1..所以你的回收视图将保持实际位置。

单击复选框时,应将状态保存在其他地方。不要依赖UI状态(因为它将被回收)。所以打电话viewHolder.checkbox.setChecked(persistedState)以前return.

我希望这是有意义的,你明白了.;-)


查看完整回答
反对 回复 2019-06-26
  • 3 回答
  • 0 关注
  • 396 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信