2014-09-27 72 views
1

我有一个ListView由具有特定布局的CustomAdapter填充。
ArrayList作为参数传递给此CustomAdapter,其中包含每个ListView元素的数据。
每个ListView元素由一个TextView(其中显示来自ArrayList的数据)和一个CheckBox在其右侧组成。ListView重复CheckBox的行为每10个项目不规则

ArrayList中的数据是正确的。当ListView被填充时,这些数据也会正确显示,并且在任何元素中都不会重复(详情请参阅下图)。

问题:当ListView的充满并显示在屏幕上,当我检查复选框中的一个,另一个复选框还检查每10元以下(参见下面的图像细节)。

1st element checked 10th element checked

2nd element checked 11th element checked

Last element checked 3rd element checked

在这些图像中可以看到,当我检查了第1个要素,10号元素也被选中。当我检查第二个元素时,第11个元素也被检查!
即使我检查最后一个元素,第三个元素也会被检查。

为什么会发生这种情况???

下面是CustomAdapter ElementContentAdapter.java的代码:

@SuppressWarnings("rawtypes") 
public class ElementContentAdapter extends BaseAdapter implements OnClickListener { 

private final Activity activity; 
private final ArrayList elements; 
private static LayoutInflater layoutInflater = null; 


public ElementContentAdapter(Activity activity, ArrayList data) { 
    this.activity = activity; 
    this.elements = data; 

    layoutInflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

public static class ViewHolder { 
    public TextView tviContent; 
} 

@Override 
public int getCount() { 
    if (elements.size() <= 0) return 1; 
    return elements.size(); 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 

@Override 
public Object getItem(int position) { 
    return position; 
} 

@Override 
public void onClick(View view) { 
    // 
} 

@SuppressLint("InflateParams") 
public View getView(int position, View convertView, ViewGroup parent) { 

    final ViewHolder viewHolder; 

    if (convertView== null) { 
     convertView = layoutInflater.inflate(R.layout.element_content_checklist, null); 

     viewHolder = new ViewHolder(); 
     viewHolder.tviContent = (TextView) convertView.findViewById(R.id.tvi_content_element_content_checklist); 

     convertView.setTag(viewHolder); 
    } else { 
     viewHolder = (ViewHolder) convertView.getTag(); 
    } 

    if (elements.size() <= 0) { 
     /** 
     * 
     */ 
    } else if(elements.size() > 0) { 
     ElementContent currentElement = null; 
     currentElement = (ElementContent) elements.get(position); 

     viewHolder.tviContent.setText(currentElement.getContent()); 

     convertView.setOnClickListener(new ElementContentOnClickListener(position)); 
    } 

    return convertView; 
} 

private class ElementContentOnClickListener implements OnClickListener { 

    private int selectedPosition; 

    ElementContentOnClickListener (int position) { 
     selectedPosition = position; 
    } 

    @Override 
    public void onClick(View view) { 
     CatMenusActivity catMenusActivity = (CatMenusActivity) activity; 
     catMenusActivity.elementoContentOnClick(selectedPosition); 
    } 

} 
} 

这里是被充气element_content_checklist.xml布局的代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:background="@color/White" 
    android:paddingBottom="10dp" 
    android:paddingRight="6dp" 
    android:paddingTop="10dp" > 

    <TextView 
     android:id="@+id/tvi_content_element_content_checklist" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_alignParentLeft="true" 
     android:layout_marginRight="10dp" 
     android:layout_toLeftOf="@+id/cbo_mark_element_content_checklist" 
     android:gravity="left" 
     android:text="@string/txt_content_element_content" 
     android:textAllCaps="false" 
     android:textColor="@color/DimGray" 
     android:textSize="14sp" 
     android:textStyle="normal" /> 

    <CheckBox 
     android:id="@+id/cbo_mark_element_content_checklist" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:layout_centerVertical="true" 
     android:button="@drawable/content_bg_checkbox_content" 
     android:checked="false" /> 

</RelativeLayout> 

ElementContent只是一个自定义的类来管理我的信息,这是从数据库中正确检索。它包含属性:elementId,contentIdcontent,以及它们各自的构造函数,getter和setter。

希望我完全了解正在发生的事情以及我想实现的目标。

非常感谢提前!

+2

这行回收为您服务。您必须将视图持有者的复选框部分复制,然后根据标志对其进行检查,对每个索引单独维护,或者作为ElementContent的一部分进行检查。点击复选框应该改变这个标志,而不仅仅是视图。 – 2014-09-27 23:35:30

回答

2

将复选框添加到您的视图持有者并将其定义为getView()方法。 然后尝试使用SparseBooleanArray,可以在单击项目时将其设置为true,并且可以在刷新视图进行更新时进行检查。

SparseBooleanArray pba=new SparseBooleanArray();//this should be global 
private class ElementContentOnClickListener implements OnClickListener { 

    private int selectedPosition; 

    ElementContentOnClickListener (int position) { 
     selectedPosition = position; 
     pba[position]=true; 

    } 

    @Override 
    public void onClick(View view) { 
     CatMenusActivity catMenusActivity = (CatMenusActivity) activity; 
     catMenusActivity.elementoContentOnClick(selectedPosition); 
    } 

} 

然后在getView() Method..manually检查选择的位置和更新复选框相应

holder.checkBox.setChecked(pba[position]); // inside getView() 
+0

是的!这是解决方案对我来说就像一个魅力! 但你有一个错误:它不是'ParseBooleanArray',是'SparseBooleanArray'(编辑你的答案)。 在'ElementContentAdapter'的构造函数中,我初始化了与我的元素数组大小相同的布尔数组。然后,我创建了一个OnCheckedChangeListener,并将其分配给ViewHolder的CheckBox,以更改布尔数组中布尔值的正确位置。最后,在'getView()'方法中,我从布尔数组中读取这个更改后的值,并使用'setChecked()'方法分配给CheckBox,并且瞧! – Ayuchuco 2014-10-16 23:05:09

+0

Yep sorry..its SparseBooleanArray :) – 2014-10-18 03:23:21