Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android listview选择中的数据无效_Android_Listview - Fatal编程技术网

Android listview选择中的数据无效

Android listview选择中的数据无效,android,listview,Android,Listview,我有一个电话簿中所有联系人的电子邮件列表视图。我的列表是一个带有复选框的自定义列表视图。现在问题如下 例如,我在列表中有20封电子邮件。如果我选择列表中的第一封电子邮件,说“A”,然后滚动列表,其他电子邮件也会被自己选择。此外,如果我再次滚动回列表,我选择的电子邮件“A”将被自己取消选择。我不知道为什么会这样 客户名单 public class EmailListAdapter extends BaseAdapter { private Context context; priv

我有一个电话簿中所有联系人的电子邮件列表视图。我的列表是一个带有复选框的自定义列表视图。现在问题如下

例如,我在列表中有20封电子邮件。如果我选择列表中的第一封电子邮件,说“A”,然后滚动列表,其他电子邮件也会被自己选择。此外,如果我再次滚动回列表,我选择的电子邮件“A”将被自己取消选择。我不知道为什么会这样

客户名单

public class EmailListAdapter extends BaseAdapter {
    private Context context;
    private ArrayList<String> data;
    DbHandler dbHandler;

    public EmailListAdapter(Context context, ArrayList<String> data) {
        this.context = context;
        this.data = data;
    }

    @Override

    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(final int i, View view, ViewGroup viewGroup) {

        final ViewHolder holder;
        dbHandler = new DbHandler(context);

        if (view == null) {
            holder = new ViewHolder();
            view = LayoutInflater.from(context).inflate(R.layout.email_custom_list, viewGroup, false);
            holder.tvContact = (TextView) view.findViewById(R.id.tv_email_name);
            holder.checkBox = (CheckBox) view.findViewById(R.id.cb_email_checkbox);

            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (compoundButton == holder.checkBox) {
                    if (b) {
//                        dbHandler.updateContactList(data.get(i).getUserID(), 1);

                    } else {
//                        dbHandler.updateContactList(data.get(i).getUserID(), 0);
                    }
                }
            }
        });


        holder.tvContact.setText(data.get(i));


        return view;
    }

    private class ViewHolder {
        TextView tvContact;
        CheckBox checkBox;

    }
公共类EmailListAdapter扩展了BaseAdapter{
私人语境;
私有数组列表数据;
DbHandler-DbHandler;
公共EmailListAdapter(上下文、ArrayList数据){
this.context=上下文;
这个数据=数据;
}
@凌驾
public int getCount(){
返回data.size();
}
@凌驾
公共对象getItem(int i){
返回null;
}
@凌驾
公共长getItemId(int i){
返回0;
}
@凌驾
公共视图getView(最终int i、视图视图、视图组视图组){
最终持票人;
dbHandler=新的dbHandler(上下文);
如果(视图==null){
holder=新的ViewHolder();
视图=LayoutFlater.from(上下文)。充气(R.layout.email\u自定义\u列表,视图组,false);
holder.tvContact=(TextView)view.findViewById(R.id.tv\u email\u name);
holder.checkBox=(checkBox)view.findViewById(R.id.cb\u email\u checkBox);
视图.设置标签(支架);
}否则{
holder=(ViewHolder)view.getTag();
}
setOnCheckedChangeListener(newcompoundButton.OnCheckedChangeListener()){
@凌驾
检查更改后的公共无效(复合按钮复合按钮,布尔b){
if(compoundButton==holder.checkBox){
如果(b){
//dbHandler.updateContactList(data.get(i).getUserID(),1);
}否则{
//dbHandler.updateContactList(data.get(i).getUserID(),0);
}
}
}
});
holder.tvContact.setText(data.get(i));
返回视图;
}
私有类视窗持有者{
TextView-tvContact;
复选框;
}

适配器正在回收您的视图。。让我们看看下面的示例:
您的
列表视图
一次显示10行,第一行为蓝色背景色。现在,如果您开始滚动,第11行将可见,第一行将隐藏。
在内部,系统会回收您的第一行并将其用作第11行。因此,您的第11行也将是蓝色的

因此,为了解决这个问题,您必须每次在
getView(…)
函数中设置背景色。在您的示例中,您必须手动保存不同复选框的状态,并在getView函数中重新应用它们

编辑 刚在StackOverflow上找到这篇文章。它更详细地讨论了这个话题:

解决方案 以下只是相关部分:

private int[] mStates;

public EmailListAdapter(Context context, ArrayList<String> data) {
    this.context = context;
    this.data = data;
    mStates = new int[data.size()];
}

@Override
public View getView(final int position, View view, ViewGroup viewGroup) {
    //...

    if (mStates[position] == 0) {
        holder.checkbox.setChecked(false);
    } else {
        holder.checkbox.setChecked(true);
    }

    holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            if (compoundButton == holder.checkBox) {
                if (b) {
                    mStates[position] = 1;
                    //dbHandler.updateContactList(data.get(i).getUserID(), 1);

                } else {
                    mStates[position] = 0;
                    //dbHandler.updateContactList(data.get(i).getUserID(), 0);
                }
            }
        }
    });

    //...
}
private int[]mStates;
公共EmailListAdapter(上下文、ArrayList数据){
this.context=上下文;
这个数据=数据;
mStates=newint[data.size()];
}
@凌驾
公共视图getView(最终整数位置、视图视图、视图组视图组){
//...
if(mStates[位置]==0){
holder.checkbox.setChecked(false);
}否则{
holder.checkbox.setChecked(true);
}
setOnCheckedChangeListener(newcompoundButton.OnCheckedChangeListener()){
@凌驾
检查更改后的公共无效(复合按钮复合按钮,布尔b){
if(compoundButton==holder.checkBox){
如果(b){
mStates[位置]=1;
//dbHandler.updateContactList(data.get(i).getUserID(),1);
}否则{
mStates[位置]=0;
//dbHandler.updateContactList(data.get(i).getUserID(),0);
}
}
}
});
//...
}

由于您使用的是视图保持架,因此在滚动时会重复使用您的复选框。当您使用视图保持架滚动时,顶部的相同复选框会再次出现在底部

当您滚动回到顶部时,复选框返回的可能不是旧的复选框

因此,您必须将每个检查表状态保存到列表中,并根据位置将其用作文本视图。

public class EmailListAdapter extends BaseAdapter {
        private Context context;
        private ArrayList<EmailModel> data;
        DbHandler dbHandler;
        int[] emails;
        ArrayList<String> emailSeperated;

        public EmailListAdapter(Context context, ArrayList<EmailModel> data) {
            this.context = context;
            this.data = data;
            emails = new int[data.size()];
        }

        @Override

        public int getCount() {
            return data.size();
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(final int i, View view, ViewGroup viewGroup) {

            final ViewHolder holder;
            dbHandler = new DbHandler(context);
            emailSeperated = new ArrayList<String>();

            if (view == null) {
                holder = new ViewHolder();
                view = LayoutInflater.from(context).inflate(R.layout.email_custom_list, viewGroup, false);
                holder.tvContact = (TextView) view.findViewById(R.id.tv_email_name);
                holder.checkBox = (CheckBox) view.findViewById(R.id.cb_email_checkbox);

                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }
    //        if (emails[i] == 0) {
    //            holder.checkBox.setChecked(false);
    //        } else {
    //            holder.checkBox.setChecked(true);
    //        }

            holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                                                           @Override
                                                           public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

                                                               if (compoundButton == holder.checkBox) {
                                                                   if (b) {
                                                                       emails[i] = 1;
                                                                       //dbHandler.updateContactList(data.get(i).getUserID(), 1);
                                                                       emailSeperated.add(data.get(i).getEmail());
                                                                       Log.e("Email values", emailSeperated.toString());

    //

                                                                   } else {
                                                                       emails[i] = 0;
                                                                       emailSeperated.remove(data.get(i).getEmail());
                                                                       Log.e("Email values", emailSeperated.toString());


                                                                   }
                                                               }

                                                           }
                                                       }

            );


            if (emails[i] == 0) {
                holder.checkBox.setChecked(false);
            } else {
                holder.checkBox.setChecked(true);
            }


            holder.tvContact.setText(data.get(i).

                            getEmail()

            );


            return view;
        }


        private class ViewHolder {
            TextView tvContact;
            CheckBox checkBox;

        }
    }
公共类EmailListAdapter扩展了BaseAdapter{
私人语境;
私有数组列表数据;
DbHandler-DbHandler;
int[]电子邮件;
ArrayList被分离;
公共EmailListAdapter(上下文、ArrayList数据){
this.context=上下文;
这个数据=数据;
emails=newint[data.size()];
}
@凌驾
public int getCount(){
返回data.size();
}
@凌驾
公共对象getItem(int i){
返回null;
}
@凌驾
公共长getItemId(int i){
返回0;
}
@凌驾
公共视图getView(最终int i、视图视图、视图组视图组){
最终持票人;
dbHandler=新的dbHandler(上下文);
emailseparated=newarraylist();
如果(视图==null){
holder=新的ViewHolder();
视图=LayoutFlater.from(上下文)。充气(R.layout.email\u自定义\u列表,视图组,false);
holder.tvContact=(TextView)view.findViewById(R.id.tv\u email\u name);
holder.checkBox=(checkBox)view.findViewById(R.id.cb\u email\u checkBox);
视图.设置标签(支架);
}否则{
holder=(ViewHolder)view.getTag();
}
//如果(电子邮件[i]==0){
//holder.checkBox.setChecked(false);
//