2011-03-25 75 views
6

我想创建一个自定义列表,其中将有复选框,允许您从列表中选择多个项目。与复选框问题的自定义列表视图

带有复选框的列表显示正常,但是如果我选中了一个复选框,然后再滚动列表中的其他项目也会被选中。

它基本上是相同的问题,因为here

我明白,这事做与Android的方式回收的观点,但我不能看到如何解决这个问题!有人可以帮我吗?

谢谢 - Mike

回答

5

您需要一个数据结构来跟踪哪些行被检查。这可以像bool[] checked那样简单。

在您的getView中,请确保您将复选框状态设置为checked[position]的内容。您也应该在getView的复选框中输入set an OnCheckedChangedListener,以便他们使用更新您的数据。

是的,ListView中的行会被回收,所以在离开getView之前,请确保为一行填充所有适当的数据。

+1

优秀的作品就像一个魅力!我不知道每次滚动时都会调用getView方法!我认为整个列表被初始化,然后getView方法再也不会被调用了! – mixkat 2011-03-25 22:06:34

+0

我以为我解决了这个问题,但我错了。它很奇怪,因为在setOnCheckedChangeListener中,我必须以相反的方式工作,即如果isChecked,则将数组的相应字段设置为false,否则设置为true。但是当我必须检查哪些盒子被检查时,所有东西都被搞乱了。注意:如果我正确设置它,即当盒子被选中时将数组字段设置为真,那么如果我向下滚动并且再次备份,则丢失所有东西。任何想法为什么发生这种情况? – mixkat 2011-03-26 18:06:42

+0

您确定即使对于循环视图调用'setChecked'?换句话说,if(convertView == null){/ *充满视图* /}/*填充视图,无论在if语句之外再循环/不可循环* /' – 2011-03-26 22:42:23

0

创建一个ArrayList<Integer>。将OnCheckChangedListener添加到您的复选框。在更改的方法中,将列表视图position添加到ArrayList<Integer>或将其删除。

在您的getView方法中,检查ArrayList<Integer>是否包含当前列表视图position。如果它包含该位置,则将选中项设置为true,否则为false。

每当您单击一个复选框时,请从ArrayList中添加或删除Integer

2

您可以尝试实现OnClickListener复选框而不是OnCheckChangedListener。它为我工作。

0

检查下面的代码 -

public View getView(int position, View convertView, ViewGroup parent){ 
      View view = convertView; 
      ViewHolder holder = new ViewHolder(); 

      if(view == null){ 

       view = inflater.inflate(R.layout.list_callcycle_blue, null);     
       holder.llContainer = (LinearLayout) view.findViewById(R.id.ll_container); 
       holder.lblLabel = (TextView) view.findViewById(R.id.txt_desc); 
       holder.cb = (CheckBox) view.findViewById(R.id.cb_store); 

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

      final Object data = getItem(position); 
      holder.lblLabel.setText(data.getDescription()); 

      holder.cb.setTag(position); 
      holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

       @Override 
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 

        int position = (Integer) buttonView.getTag(); 
        objects.get(position).setChecked(buttonView.isChecked()); 
       } 
      }); 
      holder.cb.setChecked(isChecked(position)); 

      return view; 
     } 

始终牢记,利用变化holder.cb.setOnCheckedChangeListener()任意监听它的设置数据之前,在我们的情况下,它是holder.cb.setChecked()

原因:当我们滚动,listview将回收视图,所以如果在侦听器之前使用了setchecked,那么它将根据旧的侦听器来选择值。如果我们监听后设置它,然后它会采取最新值

编辑的零件 下面部分将展示用于检索isChecked()setChecked()方法是如何检查的数据

/* 
* This function is in your Custom Adapter Class 
*/ 
private boolean isChecked(int position){ 
    return object(position).isChecked(); 
} 


/** 
* Getter Setter Class/Data Model Class that defines your object 
*/ 
private class MyObject{ 
    private boolean isChecked; 
    private String a, b, c, orWhateverYourObjectNeeds; 

    public void setChecked(boolean isChecked){ 
     this.isChecked = isChecked; 
    } 

    public boolean isChecked(){ 
     return isChecked 
    } 
} 
+0

嗨吉特帕特尔,你能解释你如何从“对象”和“isChecked(位置)”从你的代码在上面?谢谢 – 2015-02-27 15:12:49

+0

已经编辑好久了。忘了沟通,对不起 – 2015-04-12 09:08:37

相关问题