最近在做一个Android项目,在项目中要用到自定义ExpandableListView、GridView,要求是同一级别的组织信息显示在一个listview,同一级别的人员信息显示在一个listview,并且人员前面还有有复选框。下面详细介绍:
先建立一个ListViewAdapter,继承自BaseExpandableListAdapter,在ListViewAdapter实现了对组织数据的绑定,在这里我就不造数据了。
package com.yzj.example; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.content.Context; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.*; import android.widget.AdapterView.OnItemClickListener; import com.example.ListViewChildAdapter.*; public class ListViewAdapter extends BaseExpandableListAdapter implements OnItemClickListener { public static final int ItemHeight = 48;// 每项的高度 private LayoutInflater layoutInflater; private List<Map<String, String>> groupData;//组织数据 private List<List<Map<String, String>>> childData;//人员数据 private ExpandableListView expandableListView; private Context context; public ListViewAdapter(Context context, ExpandableListView expandableListView, List<Map<String, String>> groupData, List<List<Map<String, String>>> childData) { this.groupData = groupData; this.childData = childData; this.expandableListView = expandableListView; this.context = context; this.layoutInflater = LayoutInflater.from(context); } public Object getChild(int groupPosition, int childPosition) { return childData.get(groupPosition).get(childPosition); } public int getChildrenCount(int groupPosition) { return 1; } /** * 可自定义ExpandableListView */ public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ViewHolder holder; convertView = layoutInflater.inflate(R.layout.view, null); holder = new ViewHolder(); holder.gv = (MyGridView) convertView .findViewById(R.id.GridView_toolbar); holder.gv.setNumColumns(3);// 设置每行列数 holder.gv.setGravity(Gravity.CENTER);// 位置居中 holder.gv.setHorizontalSpacing(10);// 水平间隔 ListViewChildAdapter simperAdapter = new ListViewChildAdapter(context,childData.get(groupPosition)); holder.gv.setAdapter(simperAdapter);// 设置菜单Adapter holder.gv.setOnItemClickListener(this); return convertView; } /** * 可自定义list */ public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { GroupViewHolder holder; if (convertView == null) { convertView = layoutInflater.inflate(R.layout.list_group, null); holder = new GroupViewHolder(); holder.btn = (Button) convertView.findViewById(R.id.group_nextlevel); holder.text = (TextView) convertView.findViewById(R.id.group_entityname); convertView.setTag(holder); } else { holder = (GroupViewHolder) convertView.getTag(); } holder.text.setText(groupData.get(groupPosition).get("name")); holder.btn.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view) { Toast.makeText(context, "当前选中的是:Button" , Toast.LENGTH_SHORT) .show(); } }); holder.text.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view) { Toast.makeText(context, "当前选中的是:Text" , Toast.LENGTH_SHORT) .show(); } }); return convertView; } public long getChildId(int groupPosition, int childPosition) { return childPosition; } public Object getGroup(int groupPosition) { return groupData.get(groupPosition); } public int getGroupCount() { return groupData.size(); } public long getGroupId(int groupPosition) { return groupPosition; } public boolean isChildSelectable(int groupPosition, int childPosition) { return false; } public boolean hasStableIds() { return false; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { ViewHolderChild vHollder = (ViewHolderChild) view.getTag(); //在每次获取点击的item时将对于的checkbox状态改变,同时修改map的值。 vHollder.checkBox.toggle(); ListViewChildAdapter.isSelected.put(position, vHollder.checkBox.isChecked()); if(vHollder.checkBox.isChecked()){ .....//选中人员的操作 } if(vHollder.checkBox.isChecked() == false){ ......//取消选中的操作 } } static class GroupViewHolder { Button btn; TextView text; } static class ViewHolder{ MyGridView gv; } }
再建立一个ListViewChildAdapter,继承自BaseAdapter,在ListViewChildAdapter实现了对人员数据的绑定,在这里我就不造数据了。
package com.yzj.example; import android.content.Context; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.*; import android.widget.AdapterView.OnItemClickListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ListViewChildAdapter extends BaseAdapter { private LayoutInflater layoutInflater; private List<Map<String, String>> data;//人员数据 private Context context; public static Map<Integer, Boolean> isSelected; public ListViewChildAdapter(Context context, List<Map<String, String>> data){ this.layoutInflater = LayoutInflater.from(context); this.context = context; this.data = data; isSelected = new HashMap<Integer, Boolean>(); for (int i = 0; i < data.size(); i++) { isSelected.put(i, false); } } @Override public int getCount() { return data.size(); } @Override public Object getItem(int i) { return data.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int position, View covertView, ViewGroup viewGroup) { ViewHolderChild holder; if(covertView==null){ holder = new ViewHolderChild(); covertView = layoutInflater.inflate(R.layout.item_menu, null); holder.tv = (TextView) covertView.findViewById(R.id.item_text); holder.checkBox = (CheckBox) covertView.findViewById(R.id.user_select_checkbox); covertView.setTag(holder); } else { holder = (ViewHolderChild) covertView.getTag(); } holder.tv.setText(data.get(position).get("key").toString());//key 数据集中设置的键 //人员选中的操作 return covertView; } public final class ViewHolderChild{ TextView tv; CheckBox checkBox; } }
自定义MyGridView,继承自GridView。
package com.yzj.example; import android.widget.GridView; public class MyGridView extends GridView { public MyGridView(android.content.Context context, android.util.AttributeSet attrs) { super(context, attrs); } /** * 设置不滚动 */ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
下面是布局文件:
view.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" > <com.example.MyGridView android:id="@+id/GridView_toolbar" android:layout_width="fill_parent" android:layout_height="wrap_content" > </com.example.MyGridView> </LinearLayout>
mail.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" > <ExpandableListView android:id="@+id/expandableListView" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ExpandableListView> </LinearLayout>
list_group.xml
<?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="50dp" android:id="@+id/contacts_group_layout" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/group_entityname" android:layout_marginLeft="20dp" android:layout_marginTop="10dp" android:layout_marginBottom="20dp" android:gravity="center_horizontal" /> <Button android:layout_width="15dp" android:layout_height="20dp" android:id="@+id/group_nextlevel" android:background="@drawable/contacts_nextlevel" android:layout_alignParentRight="true" android:layout_marginRight="20dp" android:layout_marginTop="10dp" android:layout_marginBottom="20dp" android:focusable="false" <!--1--> android:clickable="false" <!--2--> android:focusableInTouchMode="false" <!--3--> /> <!-- 1、2、3这三句很重要,如果不加就会出现错误。由于checkbox的点击事件优先级比listview的高,所以要在checkbox中添加android:focusable="false",使得checkbox初始的时候没有获取焦点。--> <View android:layout_width="fill_parent" android:layout_height="0dp" android:background="@drawable/contacts_divider" android:layout_below="@id/group_nextlevel" /> </RelativeLayout>
item_menu.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/RelativeLayout_Item" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="5dip" > <CheckBox android:layout_width="35dp" android:layout_height="wrap_content" android:id="@+id/user_select_checkbox" android:gravity="left" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:background="@null" android:focusable="false" android:focusableInTouchMode="false" android:clickable="false" android:text=" "/> <TextView android:id="@+id/item_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" > </TextView> </RelativeLayout>