上篇文章講了自訂帶CheckBox的LISTVIEW的實現,這篇來講講自訂帶CheckBox的ExpandableListView實現,原理思想跟LISTVIEW是一樣的,只是資料存入讀取方面做 相應的修改即可。
同樣的,先建立一個工程,然後修改main.xml布局:
<?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" > <Button android:id="@+id/select_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text = "SelectAll" /> <!-- android:listSelector="@android:color/transparent"可以去掉點擊時預設的黃色背景 android:divider="@android:color/transparent"可以去掉預設的分割線 這兩個設定了後就可以換成自己的背景了。 --> <ExpandableListView android:id="@+id/expandableListView" android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" /></LinearLayout>
然後需要寫GROUP的布局檔案,我的GROUP布局檔案有一個TextView和一個ImageView組成,如listview_group_item.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/group_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dip" android:textSize="16dip" /> <RelativeLayout android:layout_width="match_parent"android:layout_height="wrap_content" > <ImageView android:id="@+id/icon" android:layout_width="30dp" android:layout_height="27dp"android:layout_marginRight="5dip" android:layout_alignParentRight="true"android:gravity="center_vertical" /></RelativeLayout> </LinearLayout>
然後還需要一個CHILD的布局檔案,我是由一個TextView和一個CheckBox組成的。如listview_item.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dip" android:textSize="12dip" /> <RelativeLayout android:layout_width="match_parent"android:layout_height="wrap_content" > <CheckBox android:id="@+id/listcb" android:layout_width="30dp" android:layout_height="27dp"android:layout_marginRight="5dip" android:layout_alignParentRight="true"android:gravity="center_vertical"android:focusable="false"android:clickable="false"android:focusableInTouchMode="false" android:button="@android:color/transparent"android:background="@drawable/music_listview_checkbox"/></RelativeLayout> </LinearLayout>
緊接著寫ExpandableListViewAdapter.java檔案:
package com.wm.example;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseExpandableListAdapter;import android.widget.CheckBox;import android.widget.ImageView;import android.widget.TextView;public class ExpandableListViewAdapter extends BaseExpandableListAdapter {private List<String>mGroupData = new ArrayList<String>();private List<HashMap<Integer,String>> mChildData= new ArrayList<HashMap<Integer,String>>(); // private Context mContext; LayoutInflater mInflater; // 用來控制CheckBox的選中狀況 private List<HashMap<Integer,Boolean>> isSelected; public ExpandableListViewAdapter(LayoutInflater inflater,Context mcontext,List<String> mGroup,List<HashMap<Integer,String>> mChild) {mInflater = inflater;//mContext = mcontext;isSelected = new ArrayList<HashMap<Integer,Boolean>>();mGroupData = mGroup;mChildData = mChild;initSelectedMap();} public void initSelectedMap(){//預設全部未勾選狀態。for(int groupId = 0; groupId < mGroupData.size();++groupId){HashMap<Integer,Boolean> mChildCheck = new HashMap<Integer,Boolean>();for(int childId = 0; childId< mChildData.get(groupId).size();++childId){mChildCheck.put(childId, false);}isSelected.add(mChildCheck);}}public void setListViewData(List<String> mGroup,List<HashMap<Integer,String>> mChild){mGroupData = mGroup;mChildData = mChild;}public void setItemCheckBoxStatus(View mView,int groupPosition,int childPostion){ViewTag holder = (ViewTag) mView.getTag(); // 改變CheckBox的狀態 holder.mCheckBox.toggle(); // 將CheckBox的選中狀況記錄下來 isSelected.get(groupPosition).put(childPostion, holder.mCheckBox.isChecked()); }public void setAllCheckBoxStatus(Boolean mFlag){for(int groupId = 0; groupId < mGroupData.size();++groupId){for(int childId = 0; childId< mChildData.get(groupId).size();++childId){isSelected.get(groupId).put(childId, mFlag);}}}public class ViewTag{public TextView mTextView;public CheckBox mCheckBox;public ImageView mIcon;}@Overridepublic Object getChild(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn mChildData.get(groupPosition).get(childPosition);}@Overridepublic long getChildId(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn childPosition;}@Overridepublic View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewTag mVobj = new ViewTag();View v;if(convertView != null){v = convertView;}else{v = mInflater.inflate(R.layout.listview_item, null);}mVobj.mTextView= (TextView) v.findViewById(R.id.name); mVobj.mCheckBox = (CheckBox) v.findViewById(R.id.listcb); mVobj.mCheckBox.setChecked(isSelected.get(groupPosition).get(childPosition)); mVobj.mTextView.setText(mChildData.get(groupPosition).get(childPosition)); v.setTag(mVobj);return v;}@Overridepublic int getChildrenCount(int groupPosition) {// TODO Auto-generated method stubreturn mChildData.get(groupPosition).size();}@Overridepublic Object getGroup(int groupPosition) {// TODO Auto-generated method stubreturn mGroupData.get(groupPosition);}@Overridepublic int getGroupCount() {// TODO Auto-generated method stubreturn mGroupData.size();}@Overridepublic long getGroupId(int groupPosition) {// TODO Auto-generated method stubreturn groupPosition;}@Overridepublic View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewTag mVobj = new ViewTag();View v;if(convertView != null){v = convertView;}else{v = mInflater.inflate(R.layout.listview_group_item, null);}mVobj.mTextView= (TextView) v.findViewById(R.id.group_name); mVobj.mTextView.setText(mGroupData.get(groupPosition)); mVobj.mIcon = (ImageView) v.findViewById(R.id.icon); v.setTag(mVobj); if (isExpanded) { mVobj.mIcon.setImageResource(R.drawable.expandlist_up); } else { mVobj.mIcon.setImageResource(R.drawable.expandlist_down); } return v;}@Overridepublic boolean hasStableIds() {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn true;}}
最後完成該ACTIVITY(ExpandableListViewCheckbox.java)的操作控制,我這裡多加了一個allSelected/allUnSelected按鈕功能:
package com.wm.example;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ExpandableListView;import android.widget.ExpandableListView.OnChildClickListener;import android.widget.ExpandableListView.OnGroupClickListener;public class ExpandableListViewCheckbox extends Activity implements OnClickListener{private static final String TAG="ExpandableListViewCheckboxActivity";private Button mBtn;private ExpandableListViewmListView;private ExpandableListViewAdapter mListViewAdapter = null;private List<String>mGroupData = new ArrayList<String>();private List<HashMap<Integer,String>> mChildData= new ArrayList<HashMap<Integer,String>>(); //control select button status(SelectedAll or UnselectAll)privateBooleanmAllSelected = false;private List<HashMap<Integer,Boolean>> mCheckedObj = new ArrayList<HashMap<Integer,Boolean>>();private int mAllSelectedSize = 0;/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mBtn=(Button) findViewById(R.id.select_btn); mBtn.setOnClickListener(this); mListView = (ExpandableListView) findViewById(R.id.expandableListView);mListView.setGroupIndicator(null);InitData();mListView.setOnGroupClickListener(new OnGroupClickListener(){@Overridepublic boolean onGroupClick(ExpandableListView parent, View v,int groupPosition, long id) {// TODO Auto-generated method stubreturn false;}});mListView.setOnChildClickListener(new OnChildClickListener() {@Overridepublic boolean onChildClick(ExpandableListView parent, View v,int groupPosition, int childPosition, long id) {// TODO Auto-generated method stub//Log.w(TAG,"********onChildClick*********");mListViewAdapter.setItemCheckBoxStatus(v, groupPosition,childPosition);if(mCheckedObj.get(groupPosition).containsKey(childPosition)){//Log.w(TAG,"****onItemClick***NEED REMOVE***");mCheckedObj.get(groupPosition).remove(childPosition);}else{//Log.w(TAG,"****onItemClick***NEED put***");mCheckedObj.get(groupPosition).put(childPosition, true);}if(getCheckedObjSize() == 0){//Log.w(TAG,"****onItemClick**NO CHECKED***");mAllSelected = false;mBtn.setText("SelectAll");}else if(getCheckedObjSize() == mAllSelectedSize){mAllSelected = true;mBtn.setText("UnselectAll");}return false;}});mListViewAdapter = new ExpandableListViewAdapter(getLayoutInflater(),this,mGroupData,mChildData);mListView.setAdapter(mListViewAdapter); } private HashMap<Integer,String> setHashMap(int size,String mstring){ HashMap<Integer,String> temp = new HashMap<Integer,String>(); for(int i=0;i< size; ++i){ temp.put(i, mstring+i); } return temp; } private void InitData(){ mGroupData.add("aaa"); mChildData.add(setHashMap(2,"a")); mGroupData.add("bbb"); mChildData.add(setHashMap(4,"b")); mGroupData.add("ccc"); mChildData.add(setHashMap(3,"c")); mGroupData.add("ddd"); mChildData.add(setHashMap(1,"d")); mGroupData.add("eee"); mChildData.add(setHashMap(2,"e")); mGroupData.add("fff"); mChildData.add(setHashMap(5,"f")); mGroupData.add("ggg"); mChildData.add(setHashMap(1,"g")); for(int groupId = 0; groupId < mGroupData.size();++groupId){ HashMap<Integer,Boolean> temp = new HashMap<Integer,Boolean>(); for(int childId = 0; childId < mChildData.get(groupId).size();++childId){ mAllSelectedSize++; } mCheckedObj.add(temp); } } private int getCheckedObjSize(){ int size =0; for(int groupId = 0; groupId < mGroupData.size();++groupId){ size += mCheckedObj.get(groupId).size(); } return size; } @Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch(v.getId()){case R.id.select_btn:{if(mAllSelected){mAllSelected = false;mBtn.setText("SelectAll");mListViewAdapter.setAllCheckBoxStatus(false); for(int groupId = 0; groupId < mGroupData.size();++groupId){ mCheckedObj.get(groupId).clear(); }}else{mAllSelected = true;mBtn.setText("UnselectAll");mListViewAdapter.setAllCheckBoxStatus(true); for(int groupId = 0; groupId < mGroupData.size();++groupId){ for(int childId = 0; childId < mChildData.get(groupId).size();++childId){ mCheckedObj.get(groupId).put(childId, true); } }}//Refresh datamListViewAdapter.notifyDataSetChanged();}break;default:break;}}}
最後運行即可測試效果。