先看一效果图、
列表中要有 图片和文字:
所以我们要实现一个自定义的 适配器。
介绍一个类:BaseExpandableListAdapter
一看就知道是 适配器的一个基类了。
所以我们自定义的适配器要 继承它。
除了 完成这个 适配器,还要有两个自定义模板,分别 组和子列表的,单元模板。如下图:
模板布局xml 要放在 layouts 下面。
main_tree_group.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="45dp" android:background="@color/white" android:gravity="center" android:orientation="vertical" > <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_tree_title_id" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="20dip" android:background="@color/white" android:text="NoData" android:textColor="@color/black" android:textSize="20dp" android:textStyle="bold" /> </LinearLayout>
子列表模板文件
main_tree_child.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="wrap_content" android:background="@color/white" android:gravity="center_vertical" android:orientation="horizontal" android:paddingBottom="5dp" android:paddingLeft="8dp" android:paddingTop="8dp" > <ImageView android:id="@+id/mainChildIcoId" android:layout_width="50dp" android:layout_height="50dp" android:src="@drawable/person_icon" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/mainChildText1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="5dp" android:background="@color/white" android:gravity="center_vertical" android:text="CNoData" android:textColor="@color/black" android:textSize="16dp" /> <TextView android:id="@+id/mainChildText2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:background="@color/white" android:gravity="center_vertical" android:text="13693668970" android:textColor="@color/black" android:textSize="12dp" /> </LinearLayout> </LinearLayout>
然后写两个对 模板文件的 bean
main_tree_group.xml 对应 bean
//父单元 class ExpandableGroupHolder { TextView title; }
main_tree_child.xml
//单元类 class ExpandableListHolder { TextView nickName; TextView phone; ImageView ioc; }
现在来实现最重要的关结。 适配器
MainListExpandableListAdapter.java
我这里把 上面两个模板对应java bean 写成 自定义适配器的内部类。
package com.main.apadter; import java.util.List; import java.util.Map; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ImageView; import android.widget.TextView; import com.main.R; public class MainListExpandableListAdapter extends BaseExpandableListAdapter { //单元类 class ExpandableListHolder { TextView nickName; TextView phone; ImageView ioc; } //父单元 class ExpandableGroupHolder { TextView title; } private List<Map<String, Object>> groupData;//组显示 private List<List<Map<String, Object>>> childData;//子列表 private LayoutInflater mGroupInflater; //用于加载group的布局xml private LayoutInflater mChildInflater; //用于加载listitem的布局xml //自宝义构造 public MainListExpandableListAdapter(Context context, List<Map<String, Object>> groupData, List<List<Map<String, Object>>> childData) { this.childData=childData; this.groupData=groupData; mChildInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mGroupInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } //必须实现 得到子数据 @Override public Object getChild(int groupPosition, int j) { return childData.get(groupPosition).get(j); } @Override public long getChildId(int groupPosition, int j) { return groupPosition; } @Override public int getChildrenCount(int i) { return childData.get(i).size(); } @Override public Object getGroup(int i) { return groupData.get(i); } @Override public int getGroupCount() { return groupData.size(); } @Override public long getGroupId(int i) { return i; } @Override public boolean hasStableIds() {//行是否具有唯一id return false; } @Override public boolean isChildSelectable(int i, int j) {//行是否可选 return false; } @Override public View getGroupView(int groupPosition, boolean flag, View convertView, ViewGroup viewgroup) { ExpandableGroupHolder holder = null; //清空临时变量holder if (convertView == null) { //判断view(即view是否已构建好)是否为空 convertView = mGroupInflater.inflate(R.layout.main_tree_group, null); holder = new ExpandableGroupHolder(); holder.title=(TextView) convertView.findViewById(R.id.main_tree_title_id); convertView.setTag(holder); } else { //若view不为空,直接从view的tag属性中获得各子视图的引用 holder = (ExpandableGroupHolder) convertView.getTag(); } String title=(String)this.groupData.get(groupPosition).get("title"); holder.title.setText(title); notifyDataSetChanged(); return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup viewgroup) { ExpandableListHolder holder = null; if (convertView == null) { convertView = mChildInflater.inflate(R.layout.main_tree_child, null); holder = new ExpandableListHolder(); holder.nickName = (TextView) convertView.findViewById(R.id.mainChildText1); holder.ioc = (ImageView) convertView.findViewById(R.id.mainChildIcoId); holder.phone = (TextView) convertView.findViewById(R.id.mainChildText2); convertView.setTag(holder); } else {//若行已初始化,直接从tag属性获得子视图的引用 holder = (ExpandableListHolder) convertView.getTag(); } Map<String,Object> unitData=this.childData.get(groupPosition).get(childPosition); holder.nickName.setText((String)unitData.get("nickName")); holder.ioc.setImageResource((Integer) unitData.get("ico")); holder.phone.setText((String)unitData.get("phone")); return convertView; } }
接下来要做的就是 利用自定义的适配器。 添加盟数据进行显了。
1、建一个 xml 设样式并设id
<?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:listSelector="@color/white" android:orientation="vertical" > <ExpandableListView android:id="@+id/expandable_id" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/white" android:drawSelectorOnTop="false" android:listSelector="@color/white" /> </LinearLayout>
创建activity
public class MainActivity extends Activity { // 声明对象 private MainListExpandableListAdapter adapter = null; List<Map<String, Object>> groups; List<List<Map<String, Object>>> childs; ExpandableListView expandableListView; private FriendsDao friendsDao; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); friendsDao=new FriendsDao(this,"ll1x.db",null,2); //为ExpandableListView准备数据 groups = new ArrayList<Map<String, Object>>(); Map<String, Object> group = new HashMap<String, Object>(); group.put("title", "我的家人"); groups.add(group); List<Map<String, Object>> child1 = new ArrayList<Map<String, Object>>(); Cursor cursor = friendsDao.selectAll(); while(cursor.moveToNext()){ Map<String, Object> child1Data1 = new HashMap<String, Object>(); child1Data1.put("nickName", cursor.getString(cursor.getColumnIndex("nickName"))); child1Data1.put("phone", cursor.getString(cursor.getColumnIndex("phone"))); child1Data1.put("ico", R.drawable.icon); child1.add(child1Data1); } childs = new ArrayList<List<Map<String, Object>>>(); childs.add(child1); // 实例化ExpandableListView对象 expandableListView = (ExpandableListView) findViewById(R.id.expandable_id); // 实例化ExpandableListView的适配器 adapter = new MainListExpandableListAdapter(getApplicationContext(), groups, childs); // 设置适配器 expandableListView.setAdapter(adapter); // 设置监听器 expandableListView.setOnChildClickListener(new OnChildClickListener() { public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { Log.d("test", "GroupPosition is " + groupPosition); Log.d("test", "ChildPosition is" + childPosition); return false; } }); } }
ok 可了。可以放到项目当去了。