2013-03-28 67 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還將爲您提供對具有所有選定視圖的類似數組的訪問,以進行處理和保存。