猿问

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

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

我知道这个问题已经被其他议员问过了,也有一些议员给出了解决办法,但问题是我没有找到适合我的应用程序的解决方案。我正在创建一个应用程序,其中我有一个屏幕,它将显示动态列表视图和列表项,一个复选框和三个文本视图(一个用于候选名称,另两个用于时钟和时钟输出时间,它们将在按日期选择时间选择后显示)。现在,我的问题是,当我选中第一个复选框(我有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中)。


人到中年有点甜
浏览 397回答 3
3回答

翻阅古今

下面是回收的实际想法和过程,这样您就可以知道您的实现和想法有什么问题。getView(也许其他人也会发现这个问题和答案)。请参阅下面的代码示例,只需忽略类型部分,因为这是附加信息。第一阶段:为循环再造而制作的物品(convertView是null):这意味着创建布局和所有项共享的公共状态。如果您有侦听器,您可以在这里添加它们,并设计它们,以便它们能够在以后的位置更改(当它被重用时)作出反应。因此,例如,通过将位置设置为相应视图上的标记,监听器可以捕获该信息,并知道它当前操作的项目。不能使用视图存储数据。因此,当侦听器更改列表项上的状态时,应将此数据持久化(在数据数组中、SQLite数据库中等),并在第二阶段.第二阶段:设置给定位置的项目状态:设置项目的可视状态。对于某一项可能单独更改的所有内容(文本、复选框状态、颜色等)都必须在这里设置。不仅更改了当前项的内容,而且还可能被另一项更改。通过这种方式,可以确保视图不用于无效状态,因为它以前是从另一个列表项中重用的。被指控的答案被删除/编辑,但建议执行getItemViewType和getViewTypeCount因此,每个列表项都有自己的视图类型。编辑的答案现在展示了如何用这里描述的方式来解决这个问题。重新实施getItemViewType和getViewTypeCount有效,但您显然误解了它的用法(请参阅下面的示例和/或这个答案).这两种方法用于使用完全不同的两个(或多个)列表项(例如,公共列表项和仅包含标题的分隔符),而不是避免回收可重用的视图。如果您使用它们来解决您的问题,您可能不理解我之前解释过的过程。例如,您有1000个项,然后执行视图类型黑客然后,您将创建1000个视图(层次结构),而可能会创建10个可重用的视图。容易..如果你只有20件左右的物品,那就没那么重要了,但是如果你把这种技术用于大清单,你只是在浪费(宝贵的)内存!下面是一个例子:void&nbsp;getItemViewType(int&nbsp;position)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;isItemAtPositionSeperator(position)&nbsp;?&nbsp;1&nbsp;:&nbsp;/*&nbsp;normal&nbsp;item&nbsp;*/&nbsp;0;}void&nbsp;int&nbsp;getViewTypeCount()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;2;&nbsp;//&nbsp;normal&nbsp;item&nbsp;and&nbsp;separator}void&nbsp;View&nbsp;getView(int&nbsp;position,&nbsp;View&nbsp;convertView,&nbsp;ViewGroup&nbsp;parent)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;type&nbsp;=&nbsp;getItemViewType(position); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;phase&nbsp;1:&nbsp;see&nbsp;my&nbsp;explanation&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(convertView&nbsp;==&nbsp;null)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(type&nbsp;==&nbsp;0)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;setup&nbsp;your&nbsp;common&nbsp;item&nbsp;view&nbsp;-&nbsp;inflate&nbsp;it&nbsp;and&nbsp;set&nbsp;to&nbsp;convertView &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;setup&nbsp;separator&nbsp;view&nbsp;-&nbsp;inflate&nbsp;it&nbsp;and&nbsp;set&nbsp;to&nbsp;convertView &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;phase&nbsp;2:&nbsp;see&nbsp;my&nbsp;explanation&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(type&nbsp;==&nbsp;0)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;set&nbsp;the&nbsp;state&nbsp;of&nbsp;the&nbsp;common&nbsp;item&nbsp;view&nbsp;based&nbsp;on&nbsp;the&nbsp;position &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;rely&nbsp;on&nbsp;the&nbsp;fact&nbsp;that&nbsp;convertView&nbsp;contains&nbsp;the&nbsp;view&nbsp;hierarchy &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;you&nbsp;created&nbsp;in&nbsp;convertView&nbsp;==&nbsp;null&nbsp;&&&nbsp;type&nbsp;==&nbsp;0 &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;set&nbsp;state&nbsp;of&nbsp;the&nbsp;separator&nbsp;based&nbsp;on&nbsp;the&nbsp;position &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;rely&nbsp;on&nbsp;the&nbsp;fact&nbsp;that&nbsp;convertView&nbsp;contains&nbsp;the&nbsp;view&nbsp;hierarchy &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;you&nbsp;created&nbsp;in&nbsp;convertView&nbsp;==&nbsp;null&nbsp;&&&nbsp;type&nbsp;!=&nbsp;0&nbsp;(else&nbsp;part) &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;convertView;}问题的实际答案.。我知道问题出在哪里,但我现在想不出一个优雅的解决方案.您的问题是将单击侦听器设置为viewHolder.checkbox.setOnCheckedChangeListener创建视图时。因此,当您滚动并且单击行为应用于错误的列表项时,它将被回收/重用。尽量不要硬码使用外部的位置final position..尝试设置viewHolder.checkbox.setTag(position)以前return然后使用(Integer) buttonView.getTag()相反position+1..所以你的回收视图将保持实际位置。单击复选框时,应将状态保存在其他地方。不要依赖UI状态(因为它将被回收)。所以打电话viewHolder.checkbox.setChecked(persistedState)以前return.我希望这是有意义的,你明白了.;-)
随时随地看视频慕课网APP

相关分类

Android
我要回答