Android ExpandableListView带有复选框,控制选中状态

Android ExpandableListView带有复选框,控制选中状态,android,checkbox,expandablelistview,Android,Checkbox,Expandablelistview,朋友们 我正在尝试编写一个在ExpandableListView中使用复选框的应用程序,我在这里遇到了一个问题,那就是维护应用程序的复选框状态,我的示例来自,我的问题是维护复选框的选中状态,每当我选中其中一个复选框并展开列表时,复选框不具有其应有的选中状态。我试图通过添加ArrayList来保存存储的位置,并在getChildView()中重新加载该位置,但仍然没有达到我想要的效果。这是我的密码 public class ElistCBox extends ExpandableListActiv

朋友们

我正在尝试编写一个在ExpandableListView中使用复选框的应用程序,我在这里遇到了一个问题,那就是维护应用程序的复选框状态,我的示例来自,我的问题是维护复选框的选中状态,每当我选中其中一个复选框并展开列表时,复选框不具有其应有的选中状态。我试图通过添加ArrayList来保存存储的位置,并在getChildView()中重新加载该位置,但仍然没有达到我想要的效果。这是我的密码

public class ElistCBox extends ExpandableListActivity {

    private static final String LOG_TAG = "ElistCBox";
    ArrayList<String > chkState = new ArrayList<String>();
    static final String colors[] = {"grey","blue","yellow","red"};
    static final String shades[][] ={ { "lightgrey","#D3D3D3","dimgray","#696969", "sgi >gray 92","#EAEAEA"},
        { "dodgerblue 2","#1C86EE","steelblue >2","#5CACEE","powderblue","#B0E0E6"},
        { "yellow 1","#FFFF00", "gold 1","#FFD700","darkgoldenrod 1"," #FFB90F" },
        {"indianred 1","#FF6A6A", "firebrick 1","#FF3030", "maroon","#800000" } };

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle)
    {
        super.onCreate(icicle);
        setContentView(R.layout.main); 
        SimpleExpandableListAdapter expListAdapter = new SimpleExpandableListAdapter( 
            this,
            createGroupList(),
            R.layout.group_row, new String[] { "colorName" },
            new int[] { R.id.childname }, createChildList(),
            R.layout.child_row,
            new String[] { "shadeName", "rgb" },
            new int[] { R.id.childname, R.id.rgb }
        ) { 
            @Override public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent)
            {
                final View v = super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);

                final CheckBox chkColor = (CheckBox)v.findViewById(R.id.check1);

                if(chkState.contains(groupPosition+","+childPosition)){
                    chkColor.setChecked(true);
                }else{
                    chkColor.setChecked(false);
                }
                chkColor.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.e("Checkbox Onclick Listener", Integer.toString(groupPosition) + " - " + Integer.toString(childPosition));
                    }
                });
                chkColor.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        Log.e("Checkbox check change Listener", Integer.toString(groupPosition) + " - " + Integer.toString(childPosition));
                        if(chkColor.isChecked()){
                            chkState.add(groupPosition+","+childPosition);
                        } else {
                            chkState.remove(groupPosition+","+childPosition); 
                        }
                    }
                });
                return super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);
            }
        };
        setListAdapter( expListAdapter );
    }

    public void onContentChanged  () {
        super.onContentChanged();
        Log.e( LOG_TAG, "onContentChanged" );
    }

    public boolean onChildClick(
            ExpandableListView parent, 
            View v, 
            int groupPosition,
            int childPosition,
            long id) {
        Log.e( LOG_TAG, "onChildClick: "+childPosition );
        CheckBox cb = (CheckBox)v.findViewById( R.id.check1 );
        if( cb != null )
        cb.toggle();
        return false;
    }

    public void  onGroupExpand  (int groupPosition) {
        Log.e( LOG_TAG,"onGroupExpand: "+groupPosition );
    }

    private List createGroupList() {
        ArrayList result = new ArrayList();
        for( int i = 0 ; i < colors.length ; ++i ) {
            HashMap m = new HashMap();
            m.put( "colorName",colors[i] );
            result.add( m );
        }
        return (List)result; 
    }

    private List createChildList() {
        ArrayList result = new ArrayList();
        for( int i = 0 ; i < shades.length ; ++i ) {
            ArrayList secList = new ArrayList();
            for( int n = 0 ; n < shades[i].length; n += 2 ) {
                HashMap child = new HashMap();
                child.put( "shadeName", shades[i][n] );
                child.put( "rgb", shades[i][n+1] ); secList.add( child );
            }
            result.add( secList );
        } 
        return result;
    }
}
公共类ElistCBox扩展了ExpandableListActivity{
私有静态最终字符串日志\u TAG=“ElistCBox”;
ArrayList chkState=新的ArrayList();
静态最终字符串颜色[]={“灰色”、“蓝色”、“黄色”、“红色”};
静态最终字符串着色[][]={{“浅灰色”、“深灰色”、“深灰色”、“深灰色”、“深灰色”、“深灰色”、“深灰色”、“深灰色”、“sgi>gray 92”、“深灰色”,
{“dodgerblue 2”、“#1C86EE”、“steelblue>2”、“#5CACEE”、“powderblue”、“#B0E0E6”},
{“黄色1”、“金色1”、“金色1”、“黑色1”、“黑色1”、“黑色90F”},
{“印度红1号”、“FF6A6A号”、“耐火砖1号”、“FF3030号”、“栗色”、“800000号”};
/**在首次创建活动时调用*/
@凌驾
创建公共空间(捆绑冰柱)
{
超级冰柱;
setContentView(R.layout.main);
SimpleExpandableListAdapter expListAdapter=新的SimpleExpandableListAdapter(
这
createGroupList(),
R.layout.group_行,新字符串[]{“colorName”},
新建int[]{R.id.childname},createChildList(),
R.layout.child_行,
新字符串[]{“shadeName”,“rgb”},
新int[]{R.id.childname,R.id.rgb}
) { 
@覆盖公共视图getChildView(最终int-groupPosition、最终int-childPosition、布尔isLastChild、视图转换视图、视图组父视图)
{
最终视图v=super.getChildView(groupPosition、childPosition、isLastChild、convertView、parent);
最终复选框chkColor=(复选框)v.findviewbyd(R.id.check1);
if(chkState.contains(groupPosition+,“+childPosition)){
chkColor.setChecked(真);
}否则{
chkColor.setChecked(假);
}
setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
Log.e(“复选框Onclick Listener”,Integer.toString(groupPosition)+“-”+Integer.toString(childPosition));
}
});
setOnCheckedChangeListener(新的OnCheckedChangeListener(){
@凌驾
检查更改后的公共无效(复合按钮视图,布尔值已检查){
Log.e(“复选框检查更改侦听器”,Integer.toString(groupPosition)+“-”+Integer.toString(childPosition));
if(chkColor.isChecked()){
chkState.add(groupPosition+,“+childPosition);
}否则{
chkState.remove(groupPosition+“,”+childPosition);
}
}
});
返回super.getChildView(groupPosition、childPosition、isLastChild、convertView、parent);
}
};
setListAdapter(expListAdapter);
}
内容更改时的公共无效(){
super.onContentChanged();
Log.e(Log_标签,“onContentChanged”);
}
公共布尔onChildClick(
ExpandableListView父级,
观点五,
int-groupPosition,
int-childPosition,
长id){
Log.e(Log_标签,onChildClick:+childPosition);
复选框cb=(复选框)v.findViewById(R.id.check1);
如果(cb!=null)
cb.toggle();
返回false;
}
public void onGroupExpand(int groupPosition){
Log.e(Log_标签,“onGroupExpand:+groupPosition”);
}
私有列表createGroupList(){
ArrayList结果=新建ArrayList();
对于(int i=0;i
这是我对这个问题的回答,你需要为每个孩子保留一个检查状态,并在点击孩子时检查它。经过一些研究,这是由于android的视图生命周期导致视图刷新,从而无法保持状态

public class MyExpandableListAdapter extends BaseExpandableListAdapter {
//Variables
// Sample data set.  children[i] contains the children (String[]) for groups[i].
private String[] groups = { "People Names", "Dog Names", "Cat Names", "Fish Names" }; //headers
private String[][] children = {
        { "Arnold", "Barry", "Chuck", "David" },
        { "Ace", "Bandit", "Cha-Cha", "Deuce" },
        { "Fluffy", "Snuggles" },
        { "Goldy", "Bubbles" }
};
private String[] group_vaues = {"PN", "DN", "CN", "FN"};
private String[][] children_values = {
        { "Ar", "Ba", "Ch", "Da" },
        { "Ace", "Ban", "Cha", "Deu" },
        { "Flu", "Snu" },
        { "Gol", "Bub" }
};
ArrayList<ArrayList<Integer>> check_states = new ArrayList<ArrayList<Integer>>();

private Context context;

//Constructors
public MyExpandableListAdapter() {

}

public MyExpandableListAdapter(Context c) {
    this.context = c;
}

//Set Methods
public void setGroupsAndValues(String[] g, String[] v) {
    this.groups = g;
    this.group_vaues = v;
}

public void setChildrenAndValues(String[][] c, String[][] v) {
    this.children = c;
    this.children_values = v;
    //initialize the states to all 0;
    for(int i = 0; i < c.length; i++) {
        ArrayList<Integer> tmp = new ArrayList<Integer>();
        for(int j = 0; j < c[i].length; j++) {
            tmp.add(0);
        }
        check_states.add(tmp);
    }
}

//Get Methods
public Object getChild(int groupPosition, int childPosition) {
    return children[groupPosition][childPosition];
}

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

public int getChildrenCount(int groupPosition) {
    return children[groupPosition].length;
}

public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
        View convertView, ViewGroup parent) {
    View grid;


   LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   grid = inflater.inflate(R.layout.specialty_list_item, parent, false);

   final int grpPos = groupPosition;
   final int childPos = childPosition;

    TextView header = (TextView)grid.findViewById(R.id.title);
    header.setText(getChild(groupPosition, childPosition).toString());
    final View tick = grid.findViewById(R.id.image);
    if(check_states.get(grpPos).get(childPos) == 1)
        tick.setVisibility(View.VISIBLE);
    else
        tick.setVisibility(View.GONE);

    grid.setOnClickListener(new OnClickListener(){
        @Override
        public void onClick(View v) {
            check_states.get(grpPos).set(childPos, 1);
            tick.setVisibility(View.VISIBLE);
        }
    });

    return grid;
}

public Object getGroup(int groupPosition) {
    return groups[groupPosition];
}

public int getGroupCount() {
    return groups.length;
}

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

public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
        ViewGroup parent) {
    View grid;

    if(convertView==null){
       grid = new View(context);
       LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       grid = inflater.inflate(R.layout.specialty_header, parent, false);
    }else{
       grid = (View)convertView;
    }

    TextView header = (TextView)grid.findViewById(R.id.specialty_header);
    header.setText(getGroup(groupPosition).toString());


    return grid;
}

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

public boolean hasStableIds() {
    return true;
}
公共类MyExpandableListAdapter扩展了BaseExpandableListAdapter{
//变数
//示例数据集.children[i]包含组[i]的子项(字符串[])。
私有字符串[]组={“人名”、“狗名”、“猫名”、“鱼名”};//头
私有字符串[][]子项={
{“阿诺德”、“巴里”、“查克”、“大卫”},
{“王牌”、“强盗”、“恰恰”、“平手”},
{“蓬松”,“依偎”},
{“黄金”、“泡泡”}
};
私有字符串[]组值={“PN”、“DN”、“CN”、“FN”};
私有字符串[][]子项\u值={
{“Ar”、“Ba”、“Ch”、“Da”},
{“Ace”、“Ban”、“Cha”、“Deu”},
{“流感”,“鼻涕”},
{“Gol”,“Bub”}
};
ArrayList check_states=新建ArrayList();
私人语境;
/
    public class MyExpandableListViewAdapter extends BaseExpandableListAdapter {
 ....

    private boolean[][] checkedState;

    private void prepareData() {
          checkedState =new boolean[itemData.length][]; 

          for (int i=0; i<itemData.length; i++) {
              groupData.append(i, String.format("Group %d", i));
              checkedState[i] = new boolean[itemData[i].length];
              Arrays.fill(checkedState[i],false);
          }
    }

    @Override
    public View getChildView(final int groupPosition, final int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {
        View itemView = convertView;
        final ViewHolder vh;
        if (itemView == null) {
           LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
           itemView = inflater.inflate(R.layout.item_view, null);
           vh = new ViewHolder();
           vh.layout = (CheckableLinearLayout)itemView.findViewById(R.id.layout);
           itemView.setTag(vh);
        } else {
           vh = (ViewHolder)itemView.getTag();
        }

        final ExpandableListView listView = ((ExpandableListView)((MainActivity)context).findViewById(R.id.list));
        final int position = listView.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));
        listView.setItemChecked(position, checkedState[groupPosition][childPosition]);

        vh.layout.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
        ((CheckableLinearLayout)v).toggle();
            checkedState[groupPosition][childPosition] = !checkedState[groupPosition][childPosition]; 
            listView.setItemChecked(position, ((CheckableLinearLayout)v).isChecked());
         }
     });
     return itemView;
  }
  ...
}
ExpandableListView list;
ArrayList<YouCat> cat = new ArrayList<YouCat>();
private YourAdapter mAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout);
    list = (ExpandableListView)findViewById(R.id.list);
    mAdapter = new YourAdapter(this, list, cat);
    if(savedInstanceState == null)
        //collect your data
    list.setAdapter(mAdapter);
    list.setItemsCanFocus(false);
    list.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
    list.setOnChildClickListener(this);
    list.setOnGroupClickListener(this);
}

public boolean onGroupClick(ExpandableListView parent, View v,
            int groupPosition, long id) {
        return cat.get(groupPosition).selected;
}

public boolean onChildClick(ExpandableListView parent, View v,
            int groupPosition, int childPosition, long id) {
        YouCat cat = new YouCat();
        YouSubCat subcat = new YouSubCat();
        subcat = cat.get(groupPosition).sub.get(childPosition);
        subcat.selected = !cat.get(groupPosition).sub.get(childPosition).selected;
        cat.get(groupPosition).sub.set(childPosition, subcat);

        boolean isGroupHasSelected = false;
        for(int i = 0; i < cat.get(groupPosition).sub.size() && !isGroupHasSelected; i ++){
            isGroupHasSelected = cat.get(groupPosition).sub.get(i).selected;
        }
        cat = cat.get(groupPosition);
        cat.selected = isGroupHasSelected;
        cat.set(groupPosition, cat);
        //mAdapter.notifyDataSetChanged();

        int position = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));
        parent.setItemChecked(position, subcat.selected);

        return true;
}

 public void onRestoreInstanceState(Bundle savedInstanceState) {
     super.onRestoreInstanceState(savedInstanceState);
     //restore data 
     cat = (ArrayList<YouCat>) savedInstanceState.getSerializable("cat");
     Type selType = new TypeToken<SparseBooleanArray>() {}.getType();
     SparseBooleanArray checked = new Gson().fromJson(savedInstanceState.getString("sel"), selType);
     //set new data to adapter and refresh
     mAdapter.refreshList(cat);
 }


 public void onSaveInstanceState(Bundle savedInstanceState) {
     super.onSaveInstanceState(savedInstanceState);
     //save data and selection from list to bundle
     savedInstanceState.putSerializable("cat", cat);
     savedInstanceState.putString("sel", new Gson().toJson(list.getCheckedItemPositions()).toString());
 }
public class YouAdapter extends BaseExpandableListAdapter{

    private Context context;
    private List<YouCat> mGroupCollection;
    private ExpandableListView mExpandableListView;

    public YouAdapter(Context context, ExpandableListView pExpandableListView,
            List<YouCat> pGroupCollection) {
        this.context = context;
        this.mGroupCollection = pGroupCollection;
        this.mExpandableListView = pExpandableListView;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return mGroupCollection.get(groupPosition).sub.get(childPosition).name;
    }

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

    class ChildHolder {
    CheckBox checkBox;
    TextView name, desc;
   }

    @Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {
        ChildHolder childHolder;
        if( convertView == null ){
            convertView = LayoutInflater.from(context).inflate(R.layout.childrow, null);
            childHolder = new ChildHolder();
            childHolder.checkBox = (CheckBox) convertView.findViewById(R.id.myCheckBox);
            childHolder.name=(TextView)convertView.findViewById(R.id.textView1);
            childHolder.desc=(TextView)convertView.findViewById(R.id.textView2);
            convertView.setTag(childHolder);
       }else{
            childHolder = (ChildHolder) convertView.getTag(); 
       }
        childHolder.name.setText(mGroupCollection.get(groupPosition).sub.get(childPosition).name);
        childHolder.desc.setText(mGroupCollection.get(groupPosition).sub.get(childPosition).desc);
        childHolder.checkBox.setChecked(mGroupCollection.get(groupPosition).sub.get(childPosition).selected);

        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return mGroupCollection.get(groupPosition).sub.size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return mGroupCollection.get(groupPosition);
    }

    @Override
    public int getGroupCount() {
        return mGroupCollection.size();
    }

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

    class GroupHolder {
      TextView title;
   }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {
        GroupHolder groupHolder;
       if( convertView == null ){
            convertView = LayoutInflater.from(context).inflate(R.layout.grouplayout,null);
            groupHolder = new GroupHolder();
            groupHolder.title = (TextView)convertView.findViewById( R.id.text1 );
            convertView.setTag(groupHolder);
       }else{
            groupHolder = (GroupHolder) convertView.getTag(); 
       }
       groupHolder.title.setText(mGroupCollection.get(groupPosition).name);
       return convertView;
    }

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

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

    public void refreshList(List<YouCat> collection){
        mGroupCollection = collection;
        notifyDataSetChanged();
        for(int g = 0; g < mGroupCollection.size(); g ++){
            if(mGroupCollection.get(g).selected)
                mExpandableListView.expandGroup(g);
            else
                mExpandableListView.collapseGroup(g);
        }
    }

}
public class YouCat implements Serializable {
        private static final long serialVersionUID = 2070450081971040619L;
        public String name = null;
        public boolean selected = false;
        public ArrayList<YouSubCat> sub = new ArrayList<YouSubCat>();
}
public class YouSubCat implements Serializable {
    private static final long serialVersionUID = -1487507723105914936L;
    public String name = null, desc = null;
    public boolean selected = false;
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >

    <CheckBox
        android:id="@+id/myCheckBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:clickable="false"
        android:focusable="false" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@+id/myCheckBox"
        android:text="TextView"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/textView1"
        android:text="TextView" />

</RelativeLayout>
<?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="wrap_content"
    android:orientation="vertical"
    android:padding="8dp" >

    <TextView
        android:id="@+id/text1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>
final SparseBooleanArray checkedItems = list.getCheckedItemPositions();
for (int i = 0; i < checkedItems.size(); i++) {
  if(checkedItems.valueAt(i))
    data = ((String)list.getItemAtPosition(checkedItems.keyAt(i)));
}