在现实开发中我们可能会遇到这样的需求,需要用listview展示数据并且可以折叠。举个例子
像淘宝购物车,可以展开商品列表也可以隐藏商品列表。那这样的效果我们怎么去实现呢?
不用慌,今天我们就用系统自带的一个控件来实现这种效果
让我们认识一下这个控件吧
ExpandableListView是android中可以实现下拉list的一个控件,是一个垂直滚动的心事两个级别列表项手风琴试图,列表项是来自ExpandableListViewaAdapter,组可以单独展开。
最终效果
是不是小伙伴们需要的效果呢?
下面看一下咋们的工程截图,很简单也很简洁(一个bean,一个adapter,一个activity,三个布局)
首先我们先来思考一个问题,假如我们的后台给我们数据形式是{item:{1,2,3},item2:{4,5,6}}
这样的话,我们就很容易的看到item就是列表头,1,2,3就是里面的内容。
但是如果我们的数据是这样的该怎么办呢?列表头和列表内容都在一个json里面如何实现折叠?
下面我们就以以上这种数据来实现这种折叠效果
首先看一下我们的activity_main布局文件
//很简单里面就是一个ExpandableListView控件
再看一下我们的布局头文件和内容文件
接着就来看一下我们的核心文件adapter
首先需要继承BaseExpandableListAdapter
public class CxdItemAdapter extends BaseExpandableListAdapter {
//实现里面的几个方法..
}
//返回一级列表的个数
@Override
public int getGroupCount() {
return mList== null ? 0:mList.size();
}
//返回每个二级列表的个数
@Override
public int getChildrenCount(int groupPosition) { //参数groupPosition表示第几个一级列表
Log.d("smyhvae", "-->" + groupPosition);
return 1;
}
//返回一级列表的单个item(返回的是对象)
@Override
public Object getGroup(int groupPosition) {
return mList.get(0);
}
//返回二级列表中的单个item(返回的是对象)
@Override
public Object getChild(int groupPosition, int childPosition) {
return mList.get(0); //不要误写成groups[groupPosition][childPosition]
}
//【重要】填充一级列表
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item_cxd_top, null);
holder.goodname = (TextView) convertView.findViewById(R.id.goodname);
holder.time = (TextView) convertView.findViewById(R.id.time);
holder.verify = (TextView) convertView.findViewById(R.id.verify);
holder.layout_bg=convertView.findViewById(R.id.layout_bg);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
mListener.setData(holder, groupPosition);
return convertView;
}
//【重要】填充二级列表
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item_cxd_content, null);
holder.username = (TextView) convertView.findViewById(R.id.username);
holder.addtime = (TextView) convertView.findViewById(R.id.addtime);
holder.goodnum = (TextView) convertView.findViewById(R.id.goodnum);
holder.goodcode = (TextView) convertView.findViewById(R.id.goodcode);
holder.goodnames = (TextView) convertView.findViewById(R.id.goodnames);
holder.salesprice = (TextView) convertView.findViewById(R.id.salesprice);
holder.begintime = (TextView) convertView.findViewById(R.id.begintime);
holder.endtime = (TextView) convertView.findViewById(R.id.endtime);
holder.salesshop = (TextView) convertView.findViewById(R.id.salesshop);
holder.btn_edit = (Button) convertView.findViewById(R.id.btn_edit);
holder.btn_delete = (Button) convertView.findViewById(R.id.btn_delete);
holder.btn_verify = (Button) convertView.findViewById(R.id.btn_verify);
holder.layout_ck=convertView.findViewById(R.id.layout_ck);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
mListener.setData2(holder, groupPosition);
return convertView;
}
接着MainActivity中使用此adapter
mAdapter = new CxdItemAdapter(this, mList, this);
expandableListView.setAdapter(mAdapter);
@Override
public void setData(CxdItemAdapter.ViewHolder viewHolder, int position) {
final CxdBean bean=mList.get(position);
viewHolder.goodname.setText(bean.getGood_name().toString().trim());
viewHolder.time.setText(
bean.getBegin_time().toString().trim().substring(0,10)
+"~"+bean.getEnd_time().toString().trim().substring(0,10));
viewHolder.verify.setText(bean.getVerify().toString().trim());
//判断当前审核状态是否是审核
if(TextUtils.isEmpty(bean.getVerify().toString().trim()) || "未审".equals(bean.getVerify().toString().trim())){
viewHolder.layout_bg.setBackgroundResource(R.color.textColorPrimary);
}else{
viewHolder.layout_bg.setBackgroundResource(R.color.step1);
}
}
@Override
public void setData2(CxdItemAdapter.ViewHolder viewHolder, int position) {
final CxdBean bean=mList.get(position);
viewHolder.username.setText(bean.getWrite_username().toString().trim());
viewHolder.addtime.setText(bean.getWrite_time().toString().trim());
viewHolder.goodnames.setText(bean.getGood_name().toString().trim());
viewHolder.goodcode.setText(bean.getGood_code().toString().trim());
viewHolder.goodnames.setText(bean.getGood_name().toString().trim());
viewHolder.salesprice.setText(bean.getGood_price().toString().trim());
viewHolder.begintime.setText(bean.getBegin_time().toString().trim().substring(0,10));
viewHolder.endtime.setText(bean.getEnd_time().toString().trim().substring(0,10));
viewHolder.salesshop.setText(bean.getGood_checks().toString().trim());
final int result=position;
//编辑
viewHolder.btn_edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CxdBean bean1=mList.get(result);
Toast.makeText(MainActivity.this,"点击了修改按钮,数据是:"+bean1.toString(),Toast.LENGTH_LONG).show();
}
});
//删除
viewHolder.btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CxdBean bean1=mList.get(result);
Toast.makeText(MainActivity.this,"点击了删除按钮,数据是:"+bean1.toString(),Toast.LENGTH_LONG).show();
}
});
//审核
viewHolder.btn_verify.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CxdBean bean1=mList.get(result);
Toast.makeText(MainActivity.this,"点击了审核按钮,数据是:"+bean1.toString(),Toast.LENGTH_LONG).show();
}
});
}
下面是完整的MainActivity代码
package lmk.com.expandablelistviewdemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lmk.com.expandablelistviewdemo.adapter.CxdItemAdapter;
import lmk.com.expandablelistviewdemo.bean.CxdBean;
public class MainActivity extends Activity implements CxdItemAdapter.DetailViewHolderListener{
//View
private ExpandableListView expandableListView;
private final static String str = "[{\"good_name\":\"小白菜\",\"id\":5,\"write_username\":\"系统管理员\"," +
"\"begin_time\":\"2019-1-27 00:00:00\",\"good_price\":999.0,\"end_time\":\"2019-2-27 00:00:00\"," +
"\"verify\":\"已审\",\"good_num\":\"100000000001\",\"write_time\":\"2019-3-27 11:52:31\"," +
"\"good_checks\":\"3004,\",\"good_code\":\"2891214\"},{\"good_name\":\"龙须菜\",\"id\":6," +
"\"write_username\":\"系统管理员\",\"begin_time\":\"2019-2-27 00:00:00\",\"good_price\":9.0," +
"\"end_time\":\"2019-11-27 00:00:00\",\"verify\":\"未审\",\"good_num\":\"100000000009\"," +
"\"write_time\":\"2019-11-27 11:39:55\",\"good_checks\":\"3032,3011,\",\"good_code\":\"2894774\"}," +
"{\"good_name\":\"芍菜\",\"id\":7,\"write_username\":\"系统管理员\",\"begin_time\":\"2019-5-27 00:00:00\"," +
"\"good_price\":7.0,\"end_time\":\"2019-1-27 00:00:00\",\"verify\":\"已审\",\"good_num\":\"100000000027\",\"write_time\":\"2019-11-27 11:40:22\",\"good_checks\":\"3012,3028,3017,3023,\",\"good_code\":\"2893357\"},{\"good_name\":\"黄瓜花\",\"id\":11,\"write_username\":\"系统管理员\",\"begin_time\":\"2019-11-27 00:00:00\",\"good_price\":9.66,\"end_time\":\"2019-11-27 00:00:00\",\"verify\":\"已审\",\"good_num\":\"100000010008\",\"write_time\":\"2019-11-27 14:47:55\",\"good_checks\":\"3009,3032,3011,3003,\",\"good_code\":\"2892564\"},{\"good_name\":\"大白菜\",\"id\":12,\"write_username\":\"系统管理员\",\"begin_time\":\"2019-11-27 00:00:00\",\"good_price\":10.0,\"end_time\":\"2019-11-27 00:00:00\",\"verify\":\"未审\",\"good_num\":\"100001010004\",\"write_time\":\"2019-11-27 14:51:11\",\"good_checks\":\"3025,3019,3009,3013,\",\"good_code\":\"2892811\"},{\"good_name\":\"芹菜\",\"id\":13,\"write_username\":\"系统管理员\",\"begin_time\":\"2019-11-27 00:00:00\",\"good_price\":-6.33,\"end_time\":\"2019-11-27 00:00:00\",\"verify\":\"已审\",\"good_num\":\"100000000013\",\"write_time\":\"2019-11-27 15:29:10\",\"good_checks\":\"3002,3030,3012,\",\"good_code\":\"2898346\"}]";
Gson gson = new Gson();
private CxdItemAdapter mAdapter;
private List mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
//将ExpandableListView原本在左边的箭头使其在右边显示
int width = getWindowManager().getDefaultDisplay().getWidth();
expandableListView.setIndicatorBounds(width-70,width);
datas();
}
private void datas() {
//模拟服务器请求数据解析数据
mList = gson.fromJson(str.toString(), new TypeToken>() {
}.getType());
mAdapter = new CxdItemAdapter(this, mList, this);
expandableListView.setAdapter(mAdapter);
}
@Override
public void setData(CxdItemAdapter.ViewHolder viewHolder, int position) {
final CxdBean bean=mList.get(position);
viewHolder.goodname.setText(bean.getGood_name().toString().trim());
viewHolder.time.setText(
bean.getBegin_time().toString().trim().substring(0,10)
+"~"+bean.getEnd_time().toString().trim().substring(0,10));
viewHolder.verify.setText(bean.getVerify().toString().trim());
//判断当前审核状态是否是审核
if(TextUtils.isEmpty(bean.getVerify().toString().trim()) || "未审".equals(bean.getVerify().toString().trim())){
viewHolder.layout_bg.setBackgroundResource(R.color.textColorPrimary);
}else{
viewHolder.layout_bg.setBackgroundResource(R.color.step1);
}
}
@Override
public void setData2(CxdItemAdapter.ViewHolder viewHolder, int position) {
final CxdBean bean=mList.get(position);
viewHolder.username.setText(bean.getWrite_username().toString().trim());
viewHolder.addtime.setText(bean.getWrite_time().toString().trim());
viewHolder.goodnames.setText(bean.getGood_name().toString().trim());
viewHolder.goodcode.setText(bean.getGood_code().toString().trim());
viewHolder.goodnames.setText(bean.getGood_name().toString().trim());
viewHolder.salesprice.setText(bean.getGood_price().toString().trim());
viewHolder.begintime.setText(bean.getBegin_time().toString().trim().substring(0,10));
viewHolder.endtime.setText(bean.getEnd_time().toString().trim().substring(0,10));
viewHolder.salesshop.setText(bean.getGood_checks().toString().trim());
final int result=position;
//编辑
viewHolder.btn_edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CxdBean bean1=mList.get(result);
Toast.makeText(MainActivity.this,"点击了修改按钮,数据是:"+bean1.toString(),Toast.LENGTH_LONG).show();
}
});
//删除
viewHolder.btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CxdBean bean1=mList.get(result);
Toast.makeText(MainActivity.this,"点击了删除按钮,数据是:"+bean1.toString(),Toast.LENGTH_LONG).show();
}
});
//审核
viewHolder.btn_verify.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CxdBean bean1=mList.get(result);
Toast.makeText(MainActivity.this,"点击了审核按钮,数据是:"+bean1.toString(),Toast.LENGTH_LONG).show();
}
});
}
}
以上就是实现上图gif中的效果,代码中都有注释,简单易懂
如果还是有些不懂的可以下载我的Demo查看