2014-09-27 71 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