【问题标题】:Selecting a specific checkbox in a long listview checks multiple checkboxes在长列表视图中选择特定复选框会检查多个复选框
【发布时间】:2013-07-30 08:28:12
【问题描述】:

我有一个带有复选框的列表视图。我单击特定项目,相应的复选框被选中,但它也会在列表视图中每 8-10 行后重复选择复选框。我理解这是因为在 android 中,仅存储可见屏幕的视图以进行内存优化。但我一直无法克服这种情况。请建议。

public class FBFriendsListAdaptor extends ArrayAdapter<FBFriendItem>{
     private final Context context;
     private static List<FBFriendItem> items;
     private SparseArray<FBFriendItem> checkedItems = new SparseArray<FBFriendItem>();
     ViewHolder holder;

     public FBFriendsListAdaptor(Context context, List<FBFriendItem> items) {
         super(context, R.layout.fb_friend_list, items);
         this.items = items;
         this.context = context;
     }

     @Override
     public FBFriendItem getItem(int position) {
        // TODO Auto-generated method stub
        return items.get(position);
     }

     public View getView(final int position, View convertView, ViewGroup parent) {

         View v = convertView;

         if (v == null) {
             LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             v = vi.inflate(R.layout.fb_friend_list, parent, false);
         }

         holder = new ViewHolder();
         holder.selectFriendCB = (CheckBox)v.findViewById(R.id.selectFriendCB);
         v.setTag(holder);

         v.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                if (checkedItems.get(position) != null){
                    checkedItems.remove(position);
                    holder.selectFriendCB.setChecked(false);
                }
                else {
                    checkedItems.put(position, items.get(position));
                    holder.selectFriendCB.setChecked(true);
                }
            }
         });

         FBFriendItem item = items.get(position);
         TextView firstNameTV = (TextView) v.findViewById(R.id.firstNameTV);
         TextView lastNameTV = (TextView) v.findViewById(R.id.lastNameTV);
         ImageView picIV = (ImageView) v.findViewById(R.id.picIV);
         if (!item.getFbId().isEmpty()) {
             firstNameTV.setText(" " + item.getFirstName());
             lastNameTV.setText(" " + item.getLastName());
             Bitmap image = item.getImage();
             if(image != null) {
                 picIV.setImageBitmap(image);
             }
         }

         return v;
     }

     public SparseArray<FBFriendItem> getCheckedItems(){
         return checkedItems;
     }

     static class ViewHolder {
         CheckBox selectFriendCB;        
     }
}

【问题讨论】:

    标签: android listview checkbox


    【解决方案1】:

    我注意到的第一件事是

         if (!item.getFbId().isEmpty()) {
             firstNameTV.setText(" " + item.getFirstName());
             lastNameTV.setText(" " + item.getLastName());
             Bitmap image = item.getImage();
             if(image != null) {
                 picIV.setImageBitmap(image);
             }
         }
    

    仅在某些情况下设置这些值是一个很大的禁忌。请记住,您的视图正在被重用,因此如果您设置了这些属性中的任何一个,您就不能指望它们具有默认值。它们可能仍然是从最后一项设置的。尝试看起来更像这样的逻辑:

         if (!item.getFbId().isEmpty()) {
             firstNameTV.setText(" " + item.getFirstName());
             lastNameTV.setText(" " + item.getLastName());
             Bitmap image = item.getImage();
             if(image == null) {
                 // reset the default because this view might have last displayed an
                 // item with a non-default value
                 picIV.setImageBitmap(myDefaultImage);
             } else {
                 picIV.setImageBitmap(image);
             }
         } else {
             // reset the defaults because this view might have last displayed an
             // item with a non-default value
             firstNameTV.setText(null);
             lastNameTV.setText(null);
             picIV.setImageBitmap(myDefaultImage);
         }
    

    接下来我注意到的是,您对检查项目的管理是完全错误的。是否检查项目是应该由ListView 管理的状态,而不是您的适配器。我不知道你想要达到什么样的外观,所以我不会具体说明如何布置你的项目,但你可能想从删除CheckBox 元素开始并查看ListView.setChoiceMode()http://developer.android.com/reference/android/widget/AbsListView.html#setChoiceMode%28int%29

    【讨论】:

    • 感谢您的回复。但主要问题是当我在列表视图中选择一个复选框时,即使我删除了上面设置名字和姓氏的代码,它也会选择多个条目。例如列表视图中显示了 100 个项目,我检查了第二个项目,这样做会分别自动检查所有第 13、24、35 个项目。我想避免这种情况。即使我在 listview 本身上添加了一个 onItemClickListener,该场景仍然存在。请对此发表评论。
    • 正如我所提到的,您所有的支票管理都是错误的。它永远不会按照您尝试的方式工作。您需要删除 CheckBox 小部件并使用 ListView.setChoiceMode()
    【解决方案2】:

    这就是它的工作方式。我在 FBFriendItem 类中添加了一个“boolean selected = false”。 下面是数组适配器中的 getView() 代码:

    public View getView(final int position, View convertView, ViewGroup parent) {
    
         ViewHolder holder = null;
    
         View v = convertView;
         if (v == null) {
             LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             v = vi.inflate(R.layout.fb_friend_list, null);
             holder = new ViewHolder();
             holder.picIV = (ImageView)v.findViewById(R.id.picIV);
             holder.firstNameTV = (TextView)v.findViewById(R.id.firstNameTV);
             holder.lastNameTV = (TextView)v.findViewById(R.id.lastNameTV);
             holder.selectFriendCB = (CheckBox)v.findViewById(R.id.selectFriendCB);
             v.setTag(holder);
             holder.selectFriendCB.setOnClickListener(new View.OnClickListener(){
                public void onClick(View v) {
                    CheckBox cb = (CheckBox)v;
                    FBFriendItem item = (FBFriendItem)cb.getTag();
                    item.setSelected(cb.isChecked());
                }
             });
         }
         else {
             holder = (ViewHolder)v.getTag();
         }
    
         FBFriendItem item = items.get(position);
         holder.picIV.setImageBitmap(item.getImageBitmap());
         holder.firstNameTV.setText(item.getFirstName());
         holder.lastNameTV.setText(item.getLastName());
         holder.selectFriendCB.setChecked(item.isSelected());
         holder.selectFriendCB.setTag(item);
    
         return v;
     }
    
     private class ViewHolder {
         ImageView picIV;
         TextView firstNameTV;
         TextView lastNameTV;
         CheckBox selectFriendCB;        
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      • 2017-01-04
      相关资源
      最近更新 更多