您的位置:首页 > 其它

Anroid(仿虎扑体育)ListView中数据按照时间\日期分组(分类)

2015-11-15 21:43 357 查看
     最近笔者在做一个项目。需求里面有一个效果是一个ListView:按带日期标题(格式:yyyy-MM-dd)分类,item为(格式:HH:mm:ss),并且在滑动过程中,当日期标题滑动到顶部的时候,进行悬浮;下一个日期标题到达顶部的时候把前一个header顶上去,废话不多少,先上效果图。

     首先是需求想要实现的效果,仿虎扑体育。






       然后是笔者实现的效果(因为项目还未上线,显示内容涉及到公司一些东西,因此显示的内容就马赛克了一下,不好意思):





      接下来说一下,这种效果需要实现的难点吧:
    1.自定义listview,实现sectionItem和contentItem的区分,并将sectionItemj进行滑动监听,在顶部进行悬浮,并进行悬浮在顶部的阴影绘制(为了有悬浮的视觉效果真实感)。(注:该自定义view参照Github上开源项目PinnedSectionListView。在末尾:笔者会贴出带下拉刷新、上拉加载的listview和不带刷新的listview的demo.在这里自定义控件的细节就不做说明了,demo里面有详细的中文注释,有兴趣的童鞋可以看看,相信大家都能看懂。O(∩_∩)O~)
     这里笔者重点分享一下如何把一个arraylist集合里面的所有数据按照某一固定的类型添加分类(分组),最后将所有数据按照分类进行整理,遍历显示。

     1、ArrayList集合里面的数据:

     因为这边从后台接收到的item的json数据日期格式为:yyyy-MM-dd HH:mm:ss;按照(yyyy-MM-dd为header,滑动到顶部要进行悬浮),(HH:mm:ss为正常的item,滑动到顶部不需要悬浮)进行重新分类。

     2、实现思路:
     其实实现也很简单!这里要利用到Map的特性。没错,猜大家已经想到了。key,String,键值对的形式来实现。具体:ArrayList里面的每条数据都含有yyyy-MM-dd HH:mm:ss。因此,我们把yyyy-MM-dd设成Map的key,凡是属于这一天的data都放在这个key下面。那么ArrayList所有的data都按照日期yyyy-MM-dd进行了分类。但是Map没办法在listview里面setAdapter呀。到了这一步就好办了,那就把Map(含Key)所有的数据都遍历出来,重新加入到一个ArrayList里面。
    

    3、关键代码:
     首先,是时间转换为yyyy-MM-dd和HH:mm:ss的工具类:

/**
* 返回 yyyy-MM-dd
*
* @param String 参数为String类型yyyy-MM-dd HH:mm:ss
* @return 返回 yyyy-MM-dd
* @throws ParseException
*/
public static String exchangeStringDate(String date) throws ParseException {
if (date != null && date.length() > 10) {
String result = date.substring(0, 10);
return result;
}else{
return null;
}

}

/**
* 返回HH:mm:ss
*
* @param String 参数为String类型
* @return 返回HH:mm:ss
* @throws ParseException
*/
public static String exchangeStringTime(String date) throws ParseException {
if (date != null && date.length() > 10) {
String result = date.substring(10, date.length());
return result;
}else{
return null;
}
}


    第二个是,通过HashMap键值对的特性,将ArrayList的数据进行分组,返回带有分组Header的ArrayList。

/**
* 通过HashMap键值对的特性,将ArrayList的数据进行分组,返回带有分组Header的ArrayList。
* @param details 从后台接受到的ArrayList的数据,其中日期格式为:yyyy-MM-dd HH:mm:ss
* @return list  返回的list是分类后的包含header(yyyy-MM-dd)和item(HH:mm:ss)的ArrayList
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static ArrayList<PinnedSectionBean> getData(List<WarnDetail> details){
//最后我们要返回带有分组的list,初始化
ArrayList<PinnedSectionBean> list = new ArrayList<PinnedSectionBean>();
//时间转换的util类
TimeManagement management = new TimeManagement();
//WarnDetail作为key是yyyy-MM-dd格式,List<WarnDetail>是对应的值是HH:mm:ss格式
Map<WarnDetail, List<WarnDetail>> map = new HashMap<WarnDetail, List<WarnDetail>>();
//按照warndetail里面的时间进行分类
WarnDetail detail = new WarnDetail();
for (int i = 0; i < details.size(); i++) {
try {
String key = management.exchangeStringDate(details.get(i).getAddtime()) ;
if (detail.getAddtime() != null && !"".equals(detail.getAddtime())) {
//判断这个Key对象有没有生成,保证是唯一对象.如果第一次没有生成,那么new一个对象,之后同组的其他item都指向这个key
boolean b = !key.equals(detail.getAddtime().toString());
if (b) {
detail = new WarnDetail();
}
}
detail.setAddtime(key);
//把属于当天yyyy-MM-dd的时间HH:mm:ss全部指向这个key
List<WarnDetail> warnDetails = map.get(detail);
//判断这个key对应的值有没有初始化,若第一次进来,这new一个arryalist对象,之后属于这一天的item都加到这个集合里面
if (warnDetails == null) {
warnDetails = new ArrayList<WarnDetail>();
}
String time = details.get(i).getAddtime();
time = management.exchangeStringTime(time);
details.get(i).setAddtime(time);
warnDetails.add(details.get(i));

map.put(detail, warnDetails);
} catch (ParseException e) {
e.printStackTrace();
}
}
//用迭代器遍历map添加到list里面
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Entry) iterator.next();
WarnDetail key = (WarnDetail) entry.getKey();
//我们的key(yyyy-MM-dd)作为标题.类别属于SECTION
list.add(new PinnedSectionBean(SECTION, key));
List<WarnDetail> li = (List<WarnDetail>) entry.getValue();
for (WarnDetail warnDetail : li) {
//对应的值(HH:mm:ss)作为标题下的item,类别属于ITEM
list.add(new PinnedSectionBean(ITEM, warnDetail));
}
}
//把分好类的hashmap添加到list里面便于显示
return list;
}

         备注:其中WarnDetail是我们的ListView显示item的实体类,大家可以根据自己具体的项目进行替换.其次,分类的类别是灵活多变的,可以按照时间分类,也可以按照地点分类,或者按照WarnDetail里面某一项数据进行分类.只要掌握Map键值对进行分类的思想,即可进行拓展延伸.

      特别提醒:对于item的点击事件:关于setItemOnclickListener中postion的问题,除了arg2-1 = postion以外,记得数据data是分类转换后的real_data哈.否则会有脚标越界的Exception.和点击item跳转错误的bug.

      最后,是笔者做的另外一个效果图,按照地点分类的list.贴上来给大家参考一下.(*^__^*)

      

;

;

    

    最后当然是源码,带下拉刷新、上拉加载的listview,按照日期分类.点击下载

     不带刷新的listview,按照日期分类.点击下载

        demo效果图:      

   

;


          友情提示:如果你还想再对list里面的数据进行排序,可以用Comparator进行排序.笔者就不再重复了,网上有很多相关资料介绍,有需求的童鞋可以Google一下.

        第一次发布博客,稍微有点紧张,如有有纰漏,欢迎各位看官指出,大家一起相互学习,有问题的话,欢迎留言,我会一一给大家回复的.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: