Listview、自定义适配器和复选框

Posted

技术标签:

【中文标题】Listview、自定义适配器和复选框【英文标题】:Listview, custom adapter and checkboxes 【发布时间】:2014-05-20 22:49:05 【问题描述】:

我的适配器有问题。代码如下:

@Override
public View getView(final int position, final View convertView, final ViewGroup parent) 
    final ViewHolder viewHolder;
    View view = convertView;
    if (view == null) 
        view = LayoutInflater.from(mContext).inflate(R.layout.row, parent, false);
        viewHolder = new ViewHolder();

        viewHolder.textTitle = (TextView) view.findViewById(R.id.title);
        viewHolder.checkBox = (CheckBox) view.findViewById(R.id.checkBox);

        viewHolder.checkBox.setTag(position);
        view.setTag(viewHolder);

        viewHolder.imageView = (ImageView) view.findViewById(R.id.activity_googlecards_card_imageview);
     else 
        viewHolder = (ViewHolder) view.getTag();
        viewHolder.checkBox.getTag(position);
    

    viewHolder.textTitle.setText(getItem(position).getTitle());

    viewHolder.checkBox.setChecked(myIntegerArrayList.contains(position));
    viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() 
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
            if (isChecked) 
                myIntegerArrayList.add(position);
             else 
                myIntegerArrayList.remove((Object) position);
            
        
    );

    return view;


private static class ViewHolder 
    TextView textTitle;
    CheckBox checkBox;

复选框本身工作正常.. 我的意思是,该位置已正确添加到我的数组列表中,但是如果(假设我检查了位置 0 的项目)我滚动到底部,然后,滚动回到顶部,项目 0 甚至返回未选中状态如果位置在我的数组列表中(用日志验证)

【问题讨论】:

从 if 中移出 viewHolder.checkBox.setTag(position); 并将 position 更改为 viewHolder.checkBox.getTag(); in onCheckedChanged viewHolder.checkBox.setTag(position);我应该把这个放在哪里? 在 else 语句之后,在 getView() out of if else 语句中 工作正常...请将其添加为回复,以便我标记它! @HpTerm Shayan 提供的解决方案效果很好 【参考方案1】:

if 中移出viewHolder.checkBox.setTag(position); 并在onCheckedChanged 中将position 更改为viewHolder.checkBox.getTag();,因此您的代码必须是这样的:

@Override
public View getView(final int position, final View convertView, final ViewGroup parent) 
    final ViewHolder viewHolder;
    View view = convertView;
    if (view == null) 
        view = LayoutInflater.from(mContext).inflate(R.layout.row, parent, false);
        viewHolder = new ViewHolder();

        viewHolder.textTitle = (TextView) view.findViewById(R.id.title);
        viewHolder.checkBox = (CheckBox) view.findViewById(R.id.checkBox);


        view.setTag(viewHolder);

        viewHolder.imageView = (ImageView) view.findViewById(R.id.activity_googlecards_card_imageview);
     else 
        viewHolder = (ViewHolder) view.getTag();
        viewHolder.checkBox.getTag(position);
    
    viewHolder.checkBox.setTag(position);

    viewHolder.textTitle.setText(getItem(position).getTitle());

    viewHolder.checkBox.setChecked(myIntegerArrayList.contains(position));
    viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() 
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
            if (isChecked) 
                myIntegerArrayList.add(viewHolder.checkBox.getTag());
             else 
                myIntegerArrayList.remove((Object) viewHolder.checkBox.getTag());
            
        
    );

    return view;

你需要搬出viewHolder.checkBox.setTag(position);,因为Recycle ListView,你需要将你在标签中的位置保存到onCheckedChanged中。

你需要在onCheckedChanged 中使用viewHolder.checkBox.getTag();,因为同样的原因。

乐于助人

【讨论】:

【参考方案2】:

只需使用

CheckBoxInListHelper.java

public class CheckBoxInListHelper 
String check = null;
String name = null;
String image = null;
boolean selected = false;

public CheckBoxInListHelper(String check, String name, String image, boolean selected) 
    super();
    this.check = check;
    this.image = image;
    this.name = name;
    this.selected = selected;


public String getcheck() 
    return check;


public void setcheck(String check) 
    this.check = check;


public String getName() 
    return name;


public void setName(String name) 
    this.name = name;


public String getimage() 
    return image;


public void setimage(String image) 
    this.image = image;



public boolean isSelected() 
    return selected;


public void setSelected(boolean selected) 
    this.selected = selected;

然后调用集合列表视图使用

 newmodelList = new ArrayList<CheckBoxInListHelper>();
  adapter=new FriendsListAdapter(FriendsList.this,newmodelList);                        
                fList.setAdapter(adapter);  

在 FriendsListAdapter 中

@Override
public View getView(int position, View convertView, ViewGroup parent) 
    ViewHolder holder = null;       
    if (convertView == null) 
        LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.friendslist_details, null);
        holder = new ViewHolder();
        holder.nameOfUser =(TextView)convertView.findViewById(R.id.name);
        holder.imageOfUser =(ImageView)convertView.findViewById(R.id.userImage);                
        holder.chkBox =(com.nuevalgo.groupbuy.CustomCheckBox)convertView.findViewById(R.id.chkbox);
        convertView.setTag(holder);

        holder.chkBox.setOnClickListener(new View.OnClickListener() 
            public void onClick(View v) 
                com.nuevalgo.groupbuy.CustomCheckBox cb = (com.nuevalgo.groupbuy.CustomCheckBox) v;
                CheckBoxInListHelper _state = (CheckBoxInListHelper) cb.getTag();                   
                _state.setSelected(cb.isChecked());                 


                FriendsList obj =   new FriendsList();
                obj.unCheck(activity);
            
        );

     else 
        holder = (ViewHolder) convertView.getTag();
    
    CheckBoxInListHelper state = (CheckBoxInListHelper) getArrayList.get(position);

    if (position == 0 || position % 2 == 0)
        convertView.setBackgroundColor(Color.parseColor("#ffffff"));
    
    else
    
        convertView.setBackgroundColor(Color.parseColor("#f2f3f1"));
              
    holder.nameOfUser.setText(state.getName());         
    if(state.getimage()!=null)
    
        imageLoader.get(state.getimage(), ImageLoader.getImageListener(holder.imageOfUser,
                R.drawable.loading, R.drawable.error));
    
    holder.chkBox.setChecked(state.isSelected());
    holder.chkBox.setTag(state);
    return convertView;

【讨论】:

【参考方案3】:
   //Try this
                    private boolean[] selection;   
                    thumbnailsselection = new boolean[myIntegerArrayList.size()];         

  //put below code in getview method                          

                    holder.checkbox.setId(position);
                    viewHolder.imageView .setId(position);



        holder.checkbox.setOnClickListener(new OnClickListener()
        
            public void onClick(View v) 

                System.out.println("click-1");

                // TODO Auto-generated method stub
                CheckBox cb = (CheckBox) v;
                int id = cb.getId();
                if (selection[id])
                                    
                    cb.setChecked(false);
                    selection[id] = false;
                 else 
                    cb.setChecked(true);
                    selection[id] = true;
                
            
        );

                    holder.checkbox.setChecked(selection[position]);
                    holder.id = position;

【讨论】:

以上是关于Listview、自定义适配器和复选框的主要内容,如果未能解决你的问题,请参考以下文章

带有复选框和自定义适配器的 ListView,片段无法正常工作

如何用文本图片和复选框过滤自定义listView?

Android - 通过复选框使用自定义适配器从列表视图中获取项目

listView中带有复选框的自定义布局:当我删除一行时,如果选中它(checkBox = true),则下一行将获得检查

为 listview 定义 onlick:在 listView 级别的 Onclick 与自定义视图适配器内的 Onclick

ListView 的自定义适配器忽略设置值