android - 在长 ListView 中选择特定复选框会检查多个复选框

标签 android listview checkbox

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

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;        
     }
}

最佳答案

我首先注意到的是

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

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

     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

关于android - 在长 ListView 中选择特定复选框会检查多个复选框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17778257/

相关文章:

checkbox - Jenkins 动态放置复选框

android - 如何在fragment中实现onBackPressed并到达HomeFragment?

android - Android 设备上的 RTSP 服务器的可能性?

android - MediaRecorder 启动失败 -19 和相机错误 100

android - 如何从其适配器刷新 listView

c# - 如何从 ListView 中访问页面的数据上下文?

php - 使用 jQuery 选择表中的所有复选框

java - 无法在 Android 中启动服务

java - Firestore 根据喜欢来订购集合

javascript - 复选框,如果选中,则需要将其价格以 div 形式求和