android ExpandableListView可扩展列表
先看一效果图、
列表中要有 图片和文字:
所以我们要实现一个自定义的 适配器。
介绍一个类: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 可了。可以放到项目当去了。