Флажок в ExpandableListView

Я использую ExpandableListView, в котором каждая группа — это TextView, а каждый дочерний элемент — это CheckBox. Я пытался реализовать что-то похожее на эту ссылку:

http://www.vogella.de/articles/AndroidListView/article.html#listadvanced_interactive

но с ExpandableListView вместо ListView. Во время выполнения он выдает странное ClassCastException при установке флажка Tag с помощью setTag(). Вот код:

public class ExpandableActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ArrayList<String> groups = new ArrayList<String>();
    List<List<OptionItem>> children = new ArrayList<List<OptionItem>>();

    for (int i = 0; i < 10; i++) {
        String groupName = "Group " + i;
        groups.add(groupName);
        List<OptionItem> temp = new ArrayList<OptionItem>();
        for (int j = 0; j < 5; j++) {
            temp.add(new OptionItem(groupName, "Child " + j));
        }
        children.add(temp);
    }

    children.get(0).get(3).setSelected(true);
    children.get(5).get(2).setSelected(true);
    children.get(8).get(1).setSelected(true);
    children.get(3).get(4).setSelected(true);

    ExpandableListView elv = (ExpandableListView) findViewById(R.id.expandableListView1);
    elv.setAdapter(new ExpandableAdapter(groups, children));

}

public static class ViewHolder {
    protected CheckBox cb;
}

public class ExpandableAdapter extends BaseExpandableListAdapter {

    private List<List<OptionItem>> list;
    private ArrayList<String> groups;

    public ExpandableAdapter(ArrayList<String> groups,
            List<List<OptionItem>> children) {
        this.groups = groups;
        this.list = children;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        if (list != null && list.size() > groupPosition
                && list.get(groupPosition) != null) {
            if (list.get(groupPosition).size() > childPosition)
                return list.get(groupPosition).get(childPosition);
        }

        return null;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public View getChildView(final int groupPosition,
            final int childPosition, boolean isLastChild, View convertView,
            ViewGroup parent) {

        View view = null;
        if (convertView == null) {
            view = getLayoutInflater().inflate(R.layout.row, null);
            final ViewHolder childHolder = new ViewHolder();
            childHolder.cb = (CheckBox) view.findViewById(R.id.checkBox1);              
            childHolder.cb
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {
                        @Override
                        public void onCheckedChanged(CompoundButton button,
                                boolean isChecked) {
                            OptionItem item = (OptionItem) childHolder.cb
                                    .getTag();
                            item.setSelected(button.isChecked());
                        }
                    });

            view.setTag(childHolder);
            childHolder.cb.setTag(list.get(groupPosition).get(childPosition));
        } else {
            view = convertView;         
            ((ViewHolder) view.getTag()).cb.setTag(list.get(groupPosition).get(childPosition));
        }

        ViewHolder holder = (ViewHolder) view.getTag();
        holder.cb.setChecked(list.get(groupPosition).get(childPosition)
                .isSelected());
        holder.cb.setText(list.get(groupPosition).get(childPosition)
                .getChildName());

        return view;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        if (list != null && list.size() > groupPosition
                && list.get(groupPosition) != null)
            return list.get(groupPosition).size();

        return 0;
    }

    @Override
    public Object getGroup(int groupPosition) {
        if (groups != null && groups.size() > groupPosition)
            return groups.get(groupPosition);

        return null;
    }

    @Override
    public int getGroupCount() {
        if (groups != null)
            return groups.size();

        return 0;
    }

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

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = getLayoutInflater().inflate(
                    android.R.layout.simple_expandable_list_item_1, null);
        }

        TextView tv = (TextView) convertView
                .findViewById(android.R.id.text1);
        tv.setText(groups.get(groupPosition));

        return convertView;
    }

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

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

и класс модели данных:

public class OptionItem {

private String groupName;
private String childName;
private boolean selected;

public OptionItem(String group, String child) {

    this.groupName = group;
    this.childName = child;
    selected = false;
}

public void setGroupName(String name) {
    this.groupName = name;
}

public void setChildName(String name) {
    this.childName = name;
}

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

public String getGroupName() {
    return groupName;
}

public String getChildName() {
    return childName;
}

public boolean isSelected() {
    return selected;
}

Пожалуйста помоги. Заранее спасибо.

EDIT : Журнал выглядит следующим образом:

  02-15 12:40:03.224: E/AndroidRuntime(423): FATAL EXCEPTION: main
02-15 12:40:03.224: E/AndroidRuntime(423): java.lang.ClassCastException: com.test.OptionItem
02-15 12:40:03.224: E/AndroidRuntime(423):  at com.test.ExpandableActivity$ExpandableAdapter.getChildView(ExpandableActivity.java:106)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.ExpandableListConnector.getView(ExpandableListConnector.java:450)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.AbsListView.obtainView(AbsListView.java:1315)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.ListView.makeAndAddView(ListView.java:1727)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.ListView.fillDown(ListView.java:652)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.ListView.fillSpecific(ListView.java:1284)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.ListView.layoutChildren(ListView.java:1558)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.AbsListView.onLayout(AbsListView.java:1147)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.view.View.layout(View.java:7035)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1249)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1125)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1042)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.view.View.layout(View.java:7035)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.view.View.layout(View.java:7035)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1249)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1125)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1042)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.view.View.layout(View.java:7035)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.view.View.layout(View.java:7035)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1045)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.os.Handler.dispatchMessage(Handler.java:99)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.os.Looper.loop(Looper.java:123)
02-15 12:40:03.224: E/AndroidRuntime(423):  at android.app.ActivityThread.main(ActivityThread.java:4627)
02-15 12:40:03.224: E/AndroidRuntime(423):  at java.lang.reflect.Method.invokeNative(Native Method)
02-15 12:40:03.224: E/AndroidRuntime(423):  at java.lang.reflect.Method.invoke(Method.java:521)
02-15 12:40:03.224: E/AndroidRuntime(423):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-15 12:40:03.224: E/AndroidRuntime(423):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-15 12:40:03.224: E/AndroidRuntime(423):  at dalvik.system.NativeStart.main(Native Method)

РЕДАКТИРОВАТЬ: я попробовал еще раз, он все еще дает то же исключение. Вот импорт, который я добавил:

import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ExpandableListView;
import android.widget.TextView;

person drink_android    schedule 14.02.2012    source источник
comment
пожалуйста, добавьте свой журнал к вопросу.   -  person Natali    schedule 14.02.2012
comment
@Natali - я добавил журнал.   -  person drink_android    schedule 15.02.2012


Ответы (2)


Пробую ваш код, проблем нет: введите сюда описание изображения

Пожалуйста, добавьте свой импорт, возможно, есть некоторые проблемы.

person Natali    schedule 15.02.2012
comment
Я попробовал еще раз, но он все еще дает то же исключение. Пожалуйста, проверьте импорт. Я добавил их к вопросу. - person drink_android; 15.02.2012
comment
ваши калсы в одной упаковке? - person Natali; 15.02.2012
comment
Да, они в одной упаковке - person drink_android; 15.02.2012
comment
chat.stackoverflow.com/rooms/7728/ - перейдите в этот чат, пожалуйста - person Natali; 15.02.2012
comment
Я я чат. Извините за задержку, появилось что-то срочное. - person drink_android; 15.02.2012

Благодаря Наталье я разобрался с проблемой. Проблема была в файле макета "row.xml". Я использовал:

<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/checkBox1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="CheckBox" />

как макет. Но когда я изменил его на:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox" />

</LinearLayout>

Оно работало завораживающе. Я думаю, это ошибка. Спасибо Наталье, что помогла мне разобраться.

person drink_android    schedule 15.02.2012