Android 初始化ExpandableListView中的复选框

Android 初始化ExpandableListView中的复选框,android,checkbox,expandablelistview,Android,Checkbox,Expandablelistview,我有一个ExpandableListView,其中每一行由一个复选框和一个TextView组成。扩展组时,我需要根据从sqlite数据库(并存储在ArrayList中)提取的数据初始化每个复选框。我有数组列表。那很容易 我不能做的是对每个复选框都进行处理。现在,不管我做什么,当我试图引用任何一个空指针错误时,我仍然会得到空指针错误。这是我的代码(在活动的onCreate方法中): expandableList.setOnGroupClickListener(新OnGroupClickListen

我有一个ExpandableListView,其中每一行由一个复选框和一个TextView组成。扩展组时,我需要根据从sqlite数据库(并存储在ArrayList中)提取的数据初始化每个复选框。我有数组列表。那很容易

我不能做的是对每个复选框都进行处理。现在,不管我做什么,当我试图引用任何一个空指针错误时,我仍然会得到空指针错误。这是我的代码(在活动的onCreate方法中):

expandableList.setOnGroupClickListener(新OnGroupClickListener(){
@凌驾
公共布尔onGroupClick(ExpandableListView父视图、视图v、int-GroupPosition、长id){
//这将初始化为0
int i=expandableList.getLastVisiblePosition()-expandableList.getFirstVisiblePosition();
对于(MySettings ThisSettings:settingsList){
系统错误println(i);
View=parent.getChildAt(i);

CheckBox=(CheckBox)view.findViewById(R.id.check_box);//我将尝试在我的应用程序中解释我的操作方式

首先,您必须创建自己的自定义适配器,该适配器允许您使用列表、数组或您使用的任何东西初始化列表:

public class CustomELVAdapter extends BaseExpandableListAdapter {


private LayoutInflater mInflater;
private ArrayList<AttributeFilter> mParent;//List containing the groups to display

public CustomELVAdapter(Context context, ArrayList<AttributeFilter> parent){
    mParent = parent;
    mInflater = LayoutInflater.from(context);
}


@Override
//counts the number of groups in the exapndable list
public int getGroupCount() {
    return mParent.size();
}

@Override
//counts the number of children items contained in a specific group
public int getChildrenCount(int groupPosition) {
    return mParent.get(groupPosition).getArrayChildren().size();
}

@Override
//gets the title ofa group
public Object getGroup(int groupPosition) {
    return mParent.get(groupPosition).getTitle();
}

@Override
//gets a child object in a group
public Object getChild(int groupPosition, int childPosition) {
    //return mParent.get(groupPosition).getArrayChildren().get(childPosition);
    return mParent.get(groupPosition).getArrayChildren().valueAt(childPosition);
}

@Override
public long getGroupId(int i) {
    return i;
}

@Override
public long getChildId(int i, int i1) {
    return i1;
}

@Override
public boolean hasStableIds() {
    return true;
}

@Override
//in this method you must set the text to see the parent/group on the list
public View getGroupView(int groupPosition, boolean b, View view, ViewGroup viewGroup) {

    if (view == null) {
        view = mInflater.inflate(R.layout.filter_list_parent, viewGroup,false);
    }

    TextView textView = (TextView) view.findViewById(R.id.filter_list_parent_textview);
    TextView detailsTV = (TextView) view.findViewById(R.id.filter_list_parent_details);

    Object parentObject = mParent.get(groupPosition);
    AttributeFilter attributeFilter = (AttributeFilter) parentObject;
    //"i" is the position of the parent/group in the list
    textView.setText(getGroup(groupPosition).toString());
    detailsTV.setText(attributeFilter.getDetails());

    //return the entire view
    return view;
}

@Override
//set a child in a group
public View getChildView(int groupPosition, int childPosition, boolean b, View view, ViewGroup viewGroup) {
    ViewHolder holder;
    if (view == null) {
        view = mInflater.inflate(R.layout.filter_list_child, viewGroup,false);
        holder = new ViewHolder();
        //holder.imageView = (ImageView) view.findViewById(R.id.filter_list_child_imageview);
        holder.checkbox = (CheckBox) view.findViewById(R.id.filter_list_child_checkbox);
        holder.title = (TextView) view.findViewById(R.id.filter_list_child_textview);

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

    try {
        Attribute attribute = mParent.get(groupPosition).getArrayChildren().valueAt(childPosition);

        holder.checkbox.setChecked(attribute.isSelected());
        holder.title.setText(attribute.getName());

        view.setTag(R.string.filter_attribute_id, attribute.getID());
    } catch (Exception e) {
        Log.e(RateDayApplication.LOG_ERROR,"CustomELVAdapter - getChildView - attribute is null");
    }

    //return the entire view
    return view;
}

@Override
public boolean isChildSelectable(int i, int i1) {
    return true;
}

@Override
public void registerDataSetObserver(DataSetObserver observer) {
    /* used to make the notifyDataSetChanged() method work */
    super.registerDataSetObserver(observer);
}

static class ViewHolder {
    CheckBox checkbox;
    TextView title;
    //ImageView icon; NOT NEEDED YET
}

}
以下是自定义类型定义
filteratAttribute
(仅供参考):

对于布局来说,有一件事很重要,您必须将复选框设置为不可聚焦,否则您将永远无法使复选框切换工作:

<?xml version="1.0" encoding="utf-8"?>



我希望不太难理解

我不是说处理项目单击。这是在用户单击任何复选框之前初始化复选框的状态。您会得到一个空指针,因为您试图在组上而不是在子组上获取复选框。我认为最好在自定义适配器中初始化复选框r、 通过重写
getChildView
函数。谢谢。我也这么想。但这改变了我的问题。我需要传递一个字符串来执行填充数组列表的查询。我不知道如何将数据传递到适配器。我可以使用共享首选项,甚至是一个小的sqlite表,然后检索它适配器中的数据。有更好的方法吗?如果保持信息已检查/未检查的数据位于
设置列表中,则应在创建新适配器时提供该数据。如果需要,我可以发布我的自定义
BaseExpandableListAdapter
ArrayList<AttributeFilter> arrayParents = new ArrayList<AttributeFilter>();//Initialize of the parents array that will be provided to the adapter.

    //Preparation of the first group (AttributeFilter is a custom type I created holding the `SparseArray` with the children and the group title)
    AttributeFilter categoriesFilter = new AttributeFilter();
    categoriesFilter.setTitle(getResources().getString(R.string.categories));
    categoriesFilter.setDetails(Tools.getLabelsStringFromSparseArray(categoriesSparseArray, prefs.getCategories()));
    categoriesSparseArray = Tools.initializeSparseArray(categoriesSparseArray, prefs.getCategories());
    categoriesFilter.setArrayChildren(categoriesSparseArray);

    //Preparation of the second group
    AttributeFilter emotionsFilter = new AttributeFilter();
    emotionsFilter.setTitle(getResources().getString(R.string.emotions));
    emotionsFilter.setDetails(Tools.getLabelsStringFromSparseArray(emotionsSparseArray, prefs.getEmotions()));
    emotionsSparseArray = Tools.initializeSparseArray(emotionsSparseArray, prefs.getEmotions());
    emotionsFilter.setArrayChildren(emotionsSparseArray);

    //Preparation of the third group
    AttributeFilter ratingsFilter = new AttributeFilter();
    ratingsFilter.setTitle(getResources().getString(R.string.ratings));
    ratingsFilter.setDetails(Tools.getLabelsStringFromSparseArray(ratingsSparseArray, prefs.getRatings()));
    ratingsSparseArray = Tools.initializeSparseArray(ratingsSparseArray, prefs.getRatings());
    ratingsFilter.setArrayChildren(ratingsSparseArray);

    //in this array we add the Parent object. We will use the arrayParents at the setAdapter
    arrayParents.add(categoriesFilter);
    arrayParents.add(emotionsFilter);
    arrayParents.add(ratingsFilter);

    //sets the adapter that provides data to the list.
    filtersELV.setAdapter(new CustomELVAdapter(this,arrayParents));//the adapter is applied on my `ExpandableListView`.
public class AttributeFilter {
private String mTitle;
private String mDetails;
private SparseArray<Attribute> mArrayChildren;

public String getTitle() {
    return mTitle;
}

public void setTitle(String mTitle) {
    this.mTitle = mTitle;
}

public String getDetails() {
    return mDetails;
}

public void setDetails(String mDetails) {
    this.mDetails = mDetails;
}

public SparseArray<Attribute> getArrayChildren() {
    return mArrayChildren;
}

public void setArrayChildren(SparseArray<Attribute> mArrayChildren) {
    this.mArrayChildren = mArrayChildren;
}

}
public class Attribute {

private int id;
private String name;
private boolean selected;
private int drawableID;

// constructor
public Attribute(int _id, String _name, int _drawable_id, boolean _selected){
    id = _id;
    name = _name;
    drawableID = _drawable_id;
    selected = _selected;       
}

public int getID() {
    return id;
}

public void setID(int _id) {
    this.id = _id;
}

public String getName() {
    return name;
}

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

public int getDrawableID() {
    return drawableID;
}

public void setDrawableID(int _drawable_id) {
    this.drawableID = _drawable_id;
}

public boolean isSelected() {
    return selected;
}

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

}
<?xml version="1.0" encoding="utf-8"?>
<CheckBox android:id="@+id/filter_list_child_checkbox"
       android:focusable="false"
       android:focusableInTouchMode="false"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>

<TextView
    android:id="@+id/filter_list_child_textview"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5dp"
    android:padding="10dp"
    android:layout_weight="1" />