ExpandableListView组件是android中一个比较常用的组件,当点击一个父item的时候可以将它的子item显示出来,像手机QQ中的好友列表就是实现的类型效果。使用ExpandableListView组件的关键就是设置它的adapter,这个adapter必须继承BaseExpandbaleListAdapter类,所以实现运用ExpandableListView的核心就是学会继承这个BaseExpanableListAdapter类。
下面是一个小例子。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.expandablelistview.MainActivity">
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list_view"/>
</RelativeLayout>
goods_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="7dp"
android:id="@+id/name_tv"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/name_tv"
android:layout_marginLeft="7dp"
android:id="@+id/price_tv"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_alignParentRight="true"
android:id="@+id/selltime_tv"/>
</RelativeLayout>
selltime.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/selltime_tv"
android:textSize="20sp"
android:gravity="left"/>
</LinearLayout>
Goods.java
package com.example.expandablelistview;
/**
* Created by Lenovo on 2017/4/24.
*/
public class Goods {
private String name;
private Double price;
private String sellTime;
public Goods(String name, Double price, String sellTime) {
this.name = name;
this.price = price;
this.sellTime = sellTime;
}
public Goods() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getSellTime() {
return sellTime;
}
public void setSellTime(String sellTime) {
this.sellTime = sellTime;
}
}
ViewHolder.java
package com.example.expandablelistview;
import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by Lenovo on 2017/4/24.
*/
public class ViewHolder {
//保存所有视图的集合
private SparseArray<View> mViews;
//转换视图
private View mConvertView;
private ViewHolder(Context mContext, ViewGroup parent,int layoutId){
mViews = new SparseArray<>();
mConvertView = LayoutInflater.from(mContext).inflate(layoutId,parent,false);
mConvertView.setTag(this);
}
public static ViewHolder get(Context context, View convertView,ViewGroup parent,int layoutId){
ViewHolder viewHolder;
if(convertView == null){
viewHolder = new ViewHolder(context,parent,layoutId);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
return viewHolder;
}
public <T extends View> T getView(int viewId){
View view = mViews.get(viewId);
//判断视图是否保存过
if(view == null){
view = mConvertView.findViewById(viewId);
mViews.put(viewId,view);
}
return (T)view;
}
/**
* 返回ConvertView
* @return
*/
public View getConvertView(){
return mConvertView;
}
public ViewHolder setTextViewText(int viewId,String text){
TextView textView = getView(viewId);
textView.setText(text);
return this;
}
}
MyExpandableListViewAdapter.java
package com.example.expandablelistview;
import android.content.Context;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import java.util.List;
import java.util.Map;
/**
* Created by Lenovo on 2017/4/24.
*/
public class MyExpandableListViewAdapter extends BaseExpandableListAdapter {
//上下文
private Context mContext;
//所有数据
private Map<String,List<Goods>> mData;
//组集合
private List<String> mGroups;
//打气筒
private LayoutInflater mInflater;
//构造函数
public MyExpandableListViewAdapter(Context mContext, Map<String, List<Goods>> mData, List<String> mGroups) {
this.mContext = mContext;
this.mData = mData;
this.mGroups = mGroups;
mInflater = LayoutInflater.from(mContext);
}
//返回组的数量
@Override
public int getGroupCount() {
return mGroups.size();
}
//返回子项目的数量
@Override
public int getChildrenCount(int groupPosition) {
String group = mGroups.get(groupPosition);
List<Goods> list = mData.get(group);
return list.size();
}
//获取组
@Override
public Object getGroup(int groupPosition) {
String group = mGroups.get(groupPosition);
return group;
}
//获取子项目
@Override
public Object getChild(int groupPosition, int childPosition) {
String group = mGroups.get(groupPosition);
List<Goods> list = mData.get(group);
return list.get(childPosition);
}
//获得组的id
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
//获取字项目的id
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
//返回组的视图
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ViewHolder viewHolder = ViewHolder.get(mContext,convertView,parent,R.layout.selltime_item);
viewHolder.setTextViewText(R.id.selltime_tv,mGroups.get(groupPosition));
return viewHolder.getConvertView();
}
//返回组中子项目的视图
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ViewHolder viewHolder = ViewHolder.get(mContext,convertView,parent,R.layout.goods_item);
String group = mGroups.get(groupPosition);
List<Goods> list = mData.get(group);
Goods goods = list.get(childPosition);
viewHolder.setTextViewText(R.id.name_tv,goods.getName());
viewHolder.setTextViewText(R.id.price_tv,"价格:"+goods.getPrice());
viewHolder.setTextViewText(R.id.selltime_tv,goods.getSellTime());
return viewHolder.getConvertView();
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
}
MainActivity.java
package com.example.expandablelistview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private ExpandableListView mListView;
private List<Goods> mGoods;
private Map<String,List<Goods>> mData;
private List<String> mGroups;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
}
private void initView() {
mListView = (ExpandableListView) findViewById(R.id.list_view);
//消掉组上的那个箭头
mListView.setGroupIndicator(null);
MyExpandableListViewAdapter adapter = new MyExpandableListViewAdapter(this,mData,mGroups);
//设置适配器
mListView.setAdapter(adapter);
convertData();
expandGroup();
}
private void initData() {
mGoods = new ArrayList<>();
mData = new HashMap<>();
mGroups = new ArrayList<>();
//模拟数据
mGoods.add(new Goods("苹果电脑",10000.0,"2011-1-1"));
mGoods.add(new Goods("苹果手机",4000.0,"2011-1-1"));
mGoods.add(new Goods("联想电脑",5000.0,"2011-2-2"));
mGoods.add(new Goods("联想手机",3000.0,"2011-2-2"));
mGoods.add(new Goods("华为电脑",5000.0,"2011-3-3"));
mGoods.add(new Goods("华为手机",4000.0,"2011-3-3"));
mGoods.add(new Goods("战神电脑",8000.0,"2011-5-1"));
}
private void expandGroup(){
//一显示界面,就让组全部展开
for(int i = 0; i < mGroups.size(); i++){
mListView.expandGroup(i);
}
//设置监听,返回true代表组不能在合起来
mListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
return true;
}
});
}
/**
* 将数据转变想要的格式
*/
private void convertData(){
for(Goods good : mGoods){
//当这个时间不在组中就要添加到组中
if(!mGroups.contains(good.getSellTime())){
mGroups.add(good.getSellTime());
List<Goods> list = new ArrayList<>();
list.add(good);
mData.put(good.getSellTime(),list);
}else{
//已经存在啦,就只用添加子项目
mData.get(good.getSellTime()).add(good);
}
}
}
}
运行结果:
虽然布局比较丑,但是用法就是这样用的,这里的ViewHolder是自己编写成一个通用的ViewHolder了。可以看看。