2013-03-28 123 views
2

我正在创建一个用于标记“学生”存在或不存在的检查列表。 我有一个listView创建成功与他们的细节和权利;一个ImageView“X”。当你点击该行时,“X”变成一个勾号!它成功地改变了我需要这个程序工作的其他东西。影响其他行的onClick onClick

我的问题是“是”,当我将其中一个“打勾”的行向外滚动时,它会恢复为“X”。我已经使用View Holder解决了这个问题。

我目前的问题是,例如,在一个6名学生名单。如果我“打勾”学生1,学生5也会变为勾号(尽管不在视野范围内)。如果我打勾学生2,学生6将打勾。反之亦然。我知道onClick代码没有针对“随机更改的行”执行,因为尽管被勾选,但这些行未被标记为“打勾”。这是很奇怪,我,这里是我的代码:

ListView listView = (ListView) findViewById(R.id.student_listview); 
    listView.setBackgroundColor(Color.TRANSPARENT); 
    listView.setCacheColorHint(Color.TRANSPARENT); 
    listView.setAdapter(new MySimpleArrayAdapter(this, studentIDarr)); 
    listView.setOnItemClickListener(new OnItemClickListener() { 
      public void onItemClick(AdapterView<?> parent, View view, 
      int position, long id) { 

      ImageView img = (ImageView) view.findViewById(R.id.icon); 

      if(img.getTag().toString().equals("checked")) { 
       checkListArr.set(position, "Absent"); 
       img.setImageResource(R.drawable.remove); 
       img.setTag("unchecked"); 
      } else { 
       checkListArr.set(position, "Present"); 
       img.setImageResource(R.drawable.checked); 
       img.setTag("checked"); 
      } 
      } 
     }); 

而且随着ViewHolder适配器...

static class ViewHolder { 
     TextView fname; 
     TextView sname; 
     TextView ID; 
     TextView email; 
     ImageView status; 
    } 

public class MySimpleArrayAdapter extends ArrayAdapter<String> { 
     private final Context context; 
     private final ArrayList<String> values; 

     public MySimpleArrayAdapter(Context context, ArrayList<String> values) { 
     super(context, R.layout.list_class_item, values); 
     this.context = context; 
     this.values = values; 
     } 

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

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

      View vi = convertView; 
      ViewHolder holder; 
      if (convertView == null) { 
       vi = inflater.inflate(R.layout.list_student_item, null); 
       holder = new ViewHolder(); 
       holder.fname = (TextView) vi.findViewById(R.id.tvFname); 
       holder.sname = (TextView) vi.findViewById(R.id.tvSname); 
       holder.ID = (TextView) vi.findViewById(R.id.tvStudentID); 
       holder.email = (TextView) vi.findViewById(R.id.tvEmail); 
       holder.status= (ImageView) vi.findViewById(R.id.icon); 

       if(checkListArr.get(position).toString().equals("Absent")) { 
        holder.status.setTag("unchecked"); 
       } else if (checkListArr.get(position).toString().equals("Present")) { 
        holder.status.setTag("checked"); 
       }  

       vi.setTag(holder); 
      } else { 
       holder = (ViewHolder) vi.getTag(); 
      }  

     if(checkListArr.get(position).toString().equals("Absent")) { 
      holder.status.setTag("unchecked"); 
     } else if (checkListArr.get(position).toString().equals("Present")) { 
      holder.status.setTag("checked"); 
     }   

     holder.ID.setText(values.get(position)); 
     holder.fname.setText(fNameArray.get(position)); 
     holder.sname.setText(sNameArray.get(position)); 
     holder.email.setText(emailArray.get(position)); 
     return vi; 
     } 
    } 

有人请我的代码中指出明显的缺陷! Thankyou阅读!

+0

setOnItemClickListener(new OnItemClickListener()注释此代码,并在自定义适配器的适配器视图中添加vi.setOnClickListener(new OnClickListener())并将所有侦听器移动到作为列表项的一部分的adpater本身。 – kumar 2013-03-28 11:11:22

回答

1

您误解了ListView如何回收以前的视图。您需要将这些更改存储在基础数据模型中。

public class Model { 

    private String fname; 
    private String sname; 
    private String email; 
    private boolean selected; 

    public Model(String fname, String sname, String email) { 
    this.fname = fname; 
    selected = false; 
    //etc 
    } 

    public String getName() { 
    return fname; 
    } 

    public void setName(String fname) { 
    this.fname = fname; 
    } 

    public boolean isSelected() { 
    return selected; 
    } 

    public void setSelected(boolean selected) { 
    this.selected = selected; 
    } 
    //etc 
} 

适配器:

private final List<Model> list; 
    private final Activity context; 

    public InteractiveArrayAdapter(Activity context, List<Model> list) { 
     super(context, R.layout.yourlayout, list); 
     this.context = context; 
     this.list = list; 
    } 

    static class ViewHolder { 
     protected TextView text; 
     protected CheckBox checkbox; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View view = null; 
     if (convertView == null) { 
      LayoutInflater inflator = context.getLayoutInflater(); 
      view = inflator.inflate(R.layout.rowbuttonlayout, null); 
      final ViewHolder viewHolder = new ViewHolder(); 
      viewHolder.text = (TextView) view.findViewById(R.id.label); 
      viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check); 
      viewHolder.checkbox 
        .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

         @Override 
         public void onCheckedChanged(CompoundButton buttonView, 
           boolean isChecked) { 
          Model element = (Model) viewHolder.checkbox 
            .getTag(); 
          element.setSelected(buttonView.isChecked()); 

         } 
        }); 
      view.setTag(viewHolder); 
      viewHolder.checkbox.setTag(list.get(position)); 
     } else { 
      view = convertView; 
      ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position)); 
     } 
     ViewHolder holder = (ViewHolder) view.getTag(); 
     holder.text.setText(list.get(position).getName()); 
     holder.checkbox.setChecked(list.get(position).isSelected()); 
     return view; 
    } 
0

无需ViewHolder

convertView已经是充气的视图。当它的值为null时膨胀。然后找到你的意见,并根据新的或convertView中的位置设置适当的值。

在适配器中执行SparseBooleanArray,其中包含切换<int Position, boolean Absence>值的方法。它优化了HashMap,类似于持有和插入这些值的类。 AdapterView<?>会给你适配器来与它进行交互。

ListView还将为您提供对具有所有选定视图的类似数组的访问,以进行处理和保存。