0

我有一个列表视图,其中有一个文本视图和一个复选框。

当我选择一个列表项时,该行中的复选框被选中,此外还选中了不同行的额外复选框。知道为什么会这样吗?

我填充列表视图的适配器:

public class  ContactAdaper extends BaseAdapter
{
    private Context myContext;
    private LayoutInflater inflater;      
    private ArrayList listname;
    private ArrayList list_no;
    private List<ContactPojo> contactList;
    private ContactPojo contactObj;
    public ContactAdaper(ContactActivity contactActivity,ArrayList listname,ArrayList list_no,List<ContactPojo> listToAddContacts)
    {
        this.myContext = contactActivity;
        this.listname = listname;
        this.list_no = list_no;
        this.contactList = listToAddContacts;
    }

    @Override
    public int getCount() 
    {
        return listname.size();
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
    {
        if (convertView == null)
        {

            inflater = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            convertView = inflater.inflate(R.layout.contact_row, null);
            final ViewHolder viewHolder = new ViewHolder();
            viewHolder.txtMobNum = (TextView) convertView.findViewById(R.id.name);
            viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);   
            viewHolder.txtName = (TextView)convertView.findViewById(R.id.id);

            convertView.setTag(viewHolder);
        }

        final ViewHolder holder = (ViewHolder) convertView.getTag();
        holder.txtMobNum.setText(list_no.get(position).toString());
        holder.txtName.setText(listname.get(position).toString());


        if(holder != null)
        {
            /*holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() 
            {

                public void onCheckedChanged(final CompoundButton buttonView, boolean isChecked) 
                {
                    //  Toast.makeText(myContext, "Selected item is :-"  +buttonView.getId(), Toast.LENGTH_LONG).show();

                    if(isChecked)
                    {
                        Toast.makeText(myContext, "Selected Name AND Number is :-"  +
                                holder.txtName.getText().toString()+", "+holder.txtMobNum.getText().toString(), Toast.LENGTH_LONG).show();

                        contactObj = new ContactPojo();
                        contactObj.name = holder.txtName.getText().toString();
                        contactObj.mobile = holder.txtMobNum.getText().toString();

                        contactList.add(contactObj);
                    }
                    else
                    {
                        removeContact(holder.txtMobNum.getText().toString());
                        notifyDataSetChanged();
                        Log.d("Cont", holder.txtName.getText().toString()+" = "+holder.txtMobNum.getText().toString()+" is removed from the list ");

                    }
                }
            });*/

            holder.checkBox.setOnClickListener(new View.OnClickListener() 
            {

                @Override
                public void onClick(View v) 
                {
                     boolean checked = ((CheckBox) v).isChecked();
                     switch(v.getId())
                     {
                        case R.id.checkBox:
                            if (checked)
                            {
                                Toast.makeText(myContext, "Selected Name AND Number is :-"  +
                                        holder.txtName.getText().toString()+", "+holder.txtMobNum.getText().toString(), Toast.LENGTH_LONG).show();

                                contactObj = new ContactPojo();
                                contactObj.name = holder.txtName.getText().toString();
                                contactObj.mobile = holder.txtMobNum.getText().toString();

                                contactList.add(contactObj);
                            }
                            else
                            {
                                removeContact(holder.txtMobNum.getText().toString());
                                notifyDataSetChanged();
                                Log.d("Cont", holder.txtName.getText().toString()+" = "+holder.txtMobNum.getText().toString()+" is removed from the list ");
                            }

                            break;
                     }
                }
            });
        }
        return convertView;              
    }      

    private void removeContact(String mobile)
    {
        Iterator<ContactPojo> it = contactList.iterator();
        while (it.hasNext())
        {
            ContactPojo contact = it.next();
            if(contact.mobile.equals(mobile)) 
            {
                it.remove();
            }
        }
    }
}    
class ViewHolder 
{
    TextView txtMobNum;
    TextView txtName;
    CheckBox checkBox;
} 

//这是我的列表行

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_margin="30dp"
    >

 <TextView 
     android:id="@+id/name"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textColor="#000000"
     android:layout_marginLeft="20dp"
     />
 <TextView 
     android:id="@+id/id"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_marginLeft="20dp"
     android:textColor="#000000"
     />
 <CheckBox 
     android:id="@+id/checkBox"
     android:tag="tagCheck"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_marginLeft="20dp"
     android:checked="false"
     />
</LinearLayout>
4

1 回答 1

0

可能是您的 convertView 没有为重用做好适当的准备。

public View getView(int position, View convertView, ViewGroup parent)当列表项“进入屏幕”时被调用(例如:在滚动期间或重新加载视图时)

传递给此方法的convertView参数包含一个已“移出屏幕”的单元格,并且可以重用于另一个单元格以节省内存。在您的代码中,convertView 中的 textViews 重新分配了它们的值,因此它们将被更新,但复选框只分配了一个新的侦听器,留下旧的选择值来呈现。当您看到另一个单元格也被选中时,这是从 convertView 加载的旧值。

要解决此问题,请跟踪应选择哪些行并在创建视图/重用 ​​converview 时相应地设置复选框值。

于 2013-04-22T13:04:29.310 回答