查询数据库的图片并且按照相册分组,其中包括全部图片

博客内容讲述了如何高效地查询数据库中的图片并按照相册的日期进行分组。作者首先对比了通过日期字符串与直接比较时间戳的方法,发现比较时间戳在大量数据时能显著提高效率。接着,为了进一步优化,手动添加日期属性进行分类,并详细解释了为何选择每行分组4个图片的原因,这与内部RecyclerView的高度设置和复用策略有关。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


public static class BucketInfo{//一个相册对象
        public int bucket_id;
        public String bucket_display_name;
        public String thumb_data;
        public int count;
        public List<PhotoInfo> innerItem;
}
    public static List<BucketInfo> test(ContentResolver cr) {
        List<BucketInfo> list = new ArrayList<BucketInfo>();
        Cursor cs = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[]{"_data", "date_added", "_id", "bucket_id",
                        "bucket_display_name"}, MediaStore.Images.Media.MIME_TYPE + " like ?",
                new String[]{"image/%"}, "date_added DESC");
        if (cs == null) {
            try {
                cs.close();
            } catch (Exception e) {
            }
            return list;
        }
        int count = cs.getCount();
        HashMap<Integer, BucketInfo> hmap = new HashMap<Integer, BucketInfo>();
        cs.moveToFirst();
        //all photos 
        BucketInfo bucketinfo_allPhotos = new BucketInfo();
        bucketinfo_allPhotos.bucket_display_name = GalleryDataServer.ALL_PHOTO_BUCKET_NAME;
        bucketinfo_allPhotos.bucket_id = GalleryDataServer.ALL_PHOTO_BUCKET_ID;
        bucketinfo_allPhotos.innerItem = new ArrayList<PhotoInfo>();
        bucketinfo_allPhotos.count = count;

        for (int i = 0; i < count; i++) {
            PhotoInfo photoInfo = new PhotoInfo();
            String data = cs.getString(0);
            photoInfo._data = data;
            long time = cs.getLong(1);
            photoInfo.date_added = time;
            int _id = cs.getInt(2);
            photoInfo._id = _id;

            int bucketid = cs.getInt(3);
            String bucketname = cs.getString(4);

            if (!hmap.containsKey(bucketid)) {
                BucketInfo bucketInfo = new BucketInfo();
                bucketInfo.bucket_display_name = bucketname;
                bucketInfo.bucket_id = bucketid;
                bucketInfo.thumb_data = data;
                bucketInfo.innerItem = new ArrayList<PhotoInfo>();
                bucketInfo.innerItem.add(photoInfo);
                bucketInfo.count = bucketInfo.innerItem.size();
                hmap.put(bucketid, bucketInfo);
                list.add(bucketInfo);
            } else {
                BucketInfo bucketInfo = hmap.remove(bucketid);
                int index = 0;
                if (list.contains(bucketInfo)) {
                    index = list.indexOf(bucketInfo);
                    list.remove(index);
                }
                bucketInfo.bucket_display_name = bucketname;
                bucketInfo.bucket_id = bucketid;
                bucketInfo.innerItem.add(photoInfo);
                bucketInfo.count = bucketInfo.innerItem.size();
                hmap.put(bucketid, bucketInfo);
                list.add(index, bucketInfo);
            }
            if(TextUtils.isEmpty(bucketinfo_allPhotos.thumb_data)){
                bucketinfo_allPhotos.thumb_data = data;
            }
            bucketinfo_allPhotos.innerItem.add(photoInfo);
            // String str = try_new SimpleDateFormat("yyyy-MM-dd").format(try_new Date(
            // time * 1000));
            cs.moveToNext();
        }
        try {
            cs.close();
        } catch (Exception e) {
        }
        list.add(0,bucketinfo_allPhotos);
        return list;
    }

2.将相册相同日期的分成一组

之前通过SimpleFormat转成yyyy-MM-dd 判断是否是同一天,在照片很多的时候,非常耗时,后面直接通过比较时间戳,效率大大的提高


    public static final int SECONDS_IN_DAY = 60 * 60 * 24;
    public static final long MILLIS_IN_DAY = 1000L * SECONDS_IN_DAY;
    public static boolean isSameDayOfMillis(final long ms1, final long ms2) {
        final long interval = ms1 - ms2;
        return interval < MILLIS_IN_DAY
                && interval > -1L * MILLIS_IN_DAY
                && toDay(ms1*1000) == toDay(ms2*1000);
    }
    private static long toDay(long millis) {
        return (millis + TimeZone.getDefault().getOffset(millis)) / MILLIS_IN_DAY;
    }
    public static ArrayList<ArrayList<PhotoInfo>> SplitPhotoInfoListByDate(List<PhotoInfo> itemList) {
        ArrayList<ArrayList<PhotoInfo>> splitedList = new ArrayList<ArrayList<PhotoInfo>>();
        ArrayList<PhotoInfo> oneDayPhotoList = new ArrayList<PhotoInfo>();
        long date=0;
        int splitedListIndex = -1;
        for (int i = 0; i < itemList.size(); i++) {
            long strDate = itemList.get(i).date_added;
            if (!isSameDayOfMillis(date,strDate)) {
                splitedListIndex++;
                date = strDate;
                oneDayPhotoList = new ArrayList<PhotoInfo>();
                splitedList.add(oneDayPhotoList);
            }
            splitedList.get(splitedListIndex).add(itemList.get(i));
        }
        return splitedList;
    }

3.手动加入日期着一个属性分类

本方法多做一件事,拆分得更细致,每一行一行都分出来的,4代表的是一行4列,这样是因为我使用的RecyclerView 嵌套的方法,内部Recyclerview高度写死,导致Recyclerview复用失效,导致卡顿,所以每一行是一个数据组,而不是每一天的数据是一个数据组

 public static ArrayList<ArrayList<PhotoInfo>> FormatePhotoInfoListFromSplitedListForAdapter(ArrayList<ArrayList<PhotoInfo>> splitedList) {
        ArrayList<ArrayList<PhotoInfo>> formatedList = new ArrayList<ArrayList<PhotoInfo>>();

        for (int i = 0; i < splitedList.size(); i++) {
            ArrayList<PhotoInfo> photoInfosInOneDay = splitedList.get(i);

            ArrayList<PhotoInfo> dataItem = new ArrayList<PhotoInfo>();
            dataItem.add(new PhotoDateInfo(photoInfosInOneDay.get(0).date_added));
            formatedList.add(dataItem);

            for (int j = 0; (j * 4) < photoInfosInOneDay.size(); j++) {
                int photoInOneDayIndex = 0;
                ArrayList<PhotoInfo> photoLineItem = new ArrayList<PhotoInfo>();
                for (int k = 0; k < 4; k++) {
                    photoInOneDayIndex = j * 4 + k;
                    if (photoInOneDayIndex < photoInfosInOneDay.size()) {
                        photoLineItem.add(photoInfosInOneDay.get(photoInOneDayIndex));
                    } else {
                        break;
                    }
                }

                formatedList.add(photoLineItem);
            }
        }

        return formatedList;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值