最近项目中需要做一个按标题分组的ListView,要实现的效果如下图
标题是月份,在按月份的数据是改月份的账单数据。开始想的就是在列表的某个位置插入另一个布局,其他的地方和普通的ListView一样。并不知道该在那个位置插入这些标题。所以需要在数据上进行处理,另外需要知道每个item位置应该用什么类型的item view。
具体实现如下:
1.先对数据进行处理:
需要处理的json数据格式如下图 , billList数组是每个需要展示的账单item,month字段是一个组item标题。
根据数据和展示的需求,创建一个数据实体类,代码如下:
public static class ContentBean {
private String month; //存储每组数据的月份标题
private List<BillListResponse.ContentBean.BillListBean> billList;//一组数据的list列表
ListView的适配器(关键)
public class AllRecordBillAdapter extends BaseAdapter{
//需要展示的数据 , 多组数据的集合
List<BillListResponse.ContentBean> mRecordContentList;
private Context mContext;
private LayoutInflater mInflater;
//类别的ITEM 月份
private static final int TYPE_ITEM = 0;
//具体账单内容
private static final int CONTENT_ITEM = 1;
public AllRecordBillAdapter(Context context , List<BillListResponse.ContentBean> billRecordBeanList) {
mRecordContentList = billRecordBeanList;
mContext = context;
mInflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
//计算出所有的要展示的数据item的个数,包括每一个
int count = 0;
if (null != mRecordContentList) {
// 所有分类中item的总个数
for (BillListResponse.ContentBean contentBean : mRecordContentList) {
count += (contentBean.getBillList().size()+1);
}
}
return count;
}
@Override
public Object getItem(int position) {
// 异常情况处理
if (null == mRecordContentList || position < 0 || position > getCount()) {
return null;
}
//同一分类内,第一个元素的索引值
int groupFirstIndex = 0;
for (BillListResponse.ContentBean contentBean : mRecordContentList) {
int size = contentBean.getBillList().size()+1;
// 在当前分类中的索引值
int categoryIndex = position - groupFirstIndex;
// item在当前分类内
if (categoryIndex < size) {
if(categoryIndex == 0){
//首选项返回的是月份
return contentBean.getMonth();
}else{
//返回其他数据
return contentBean.getBillList().get(categoryIndex-1);
}
}
// 索引移动到当前分类结尾,即下一个分类第一个元素索引
groupFirstIndex += size;
}
return null;
}
@Override
public int getItemViewType(int position) {
// 异常情况处理
if (null == mRecordContentList || position < 0|| position > getCount()) {
return TYPE_ITEM;
}
int groupFirstIndex = 0;
for (BillListResponse.ContentBean contentBean : mRecordContentList){
int size = contentBean.getBillList().size()+1;
// 在当前分类中的索引值
int categoryIndex = position - groupFirstIndex;
//分组的标题
if (categoryIndex == 0) {
return TYPE_ITEM;
}
groupFirstIndex += size;
}
//内容项
return CONTENT_ITEM;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int itemViewType = getItemViewType(position);
switch (itemViewType) {
case TYPE_ITEM:
if (null == convertView) {
convertView = mInflater.inflate(R.layout.bill_record_item_header, null);
}
TextView textView = (TextView) convertView.findViewById(R.id.bill_record_header);
String itemValue = (String) getItem(position);
textView.setText(itemValue);
break;
case CONTENT_ITEM:
RecordViewHolder viewHolder = null;
if (null == convertView) {
convertView = mInflater.inflate(R.layout.bill_record_content_item, null);
viewHolder = new RecordViewHolder();
viewHolder.contentWeek = (TextView) convertView.findViewById(R.id.bill_record_week_info);
viewHolder.contentDay = (TextView) convertView.findViewById(R.id.bill_record_day_info);
viewHolder.contentAmount = (TextView) convertView.findViewById(R.id.bill_record_amount_info);
viewHolder.contentType = (TextView) convertView.findViewById(R.id.bill_record_type_info);
convertView.setTag(viewHolder);
} else {
viewHolder = (RecordViewHolder) convertView.getTag();
}
// 绑定数据
BillListResponse.ContentBean.BillListBean billListBean = (BillListResponse.ContentBean.BillListBean)getItem(position);
String createTime = billListBean.getCreateTime();
String date = createTime.substring(5, 10);
String week = dayForWeek(createTime.substring(0,10));
viewHolder.contentWeek.setText(week);
viewHolder.contentType.setText(billListBean.getItemName());
viewHolder.contentDay.setText(date);
viewHolder.contentAmount.setText(billListBean.getPrice()+"");
break;
}
return convertView;
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return getItemViewType(position) != TYPE_ITEM;
}
class RecordViewHolder {
TextView contentWeek;
TextView contentDay;
TextView contentAmount;
TextView contentType;
}
public static String dayForWeek(String pTime){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
try {
c.setTime(format.parse(pTime));
} catch (ParseException e) {
e.printStackTrace();
}
int dayForWeek = 0;
if(c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY){
dayForWeek = 7;
}else{
dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
}
if(dayForWeek == 1) {
return "周一";
}else if(dayForWeek == 2){
return "周二";
}else if(dayForWeek == 3){
return "周三";
}else if(dayForWeek == 4){
return "周四";
} else if(dayForWeek == 5){
return "周五";
}else if(dayForWeek == 6){
return "周六";
}else if(dayForWeek == 7){
return "周日";
}
return null;
}