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