设计一个图片选择器(中篇)

上篇中提到使用CursorLoader来加载媒体数据,以微信的图片选择器为例,需要一个文件夹列表和文件夹内详情两个CursorLoader。

文件夹列表的CursorLoader

确定使用的URI:当只需要一种类型时可以使用独立的URI,例如只需要图片则使用:IMAGE_URI(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);只需要视频则使用VIDEO_URI;但是如果需要混合查询(图片和视频都)则需要使用FILE_URI(MediaStore.Files.getContentUri("external"))。

确定Projection:文件夹列表需要名称,数量,封面图,封面类型,id(bucket_id用于查询),详细字段就是下面这些

    private static final String[] PROJECTION = {
            MediaStore.MediaColumns._ID,
            MediaStore.Images.Media.BUCKET_ID,
            MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
            MediaStore.MediaColumns.DATA,
            MediaStore.MediaColumns.MIME_TYPE,
            "count(*) as " + COLUMN_COUNT};

备注:其中count是使用group by查询出的数量。而data和mimeType则是根据排序查出的第一条数据。

确定查询条件Selection:根据需要查询的类型来构建查询条件,其中主要使用MIME_TYPE来查询,例如通常图片的类型有:jpeg(image/jpeg),png(image/png),bmp(image/bmp),gif(image/gif)等等,关于mime type可以参考这个系统源码链接。然后加上大小必须大于0,group by bucket_id,如果是混合查询还需要加上media_type,因为需要封面可能是视频,而图片文件夹是不能以视频为封面的。

确定排序条件order by:一般使用修改日期排序,就是date_modified desc。

根据返回的cursor构建文件夹列表的List:混合查询时,第一个item是所有的文件的集合,遍历整个cursor把数量相加,然后构建成第一条数据;如果有视频则第二个item是所有视频的集合,遍历的过程中相加视频的数量;后面就是每个图片文件夹的列表;最后得到整个文件夹列表,然后就是根据列表设置RecyclerView的adapter,显示列表的内容,当选择某个文件夹时则对详情进行重新查询并显示。

文件夹内详情的CursorLoader

当选择一个文件夹时,根据文件夹的信息来构建查询的条件;

查询的URI:如果是混合查询的第一条,则URI是FILE_URI;如果是图片文件夹或视频文件夹则使用IMAGE或VIDEO的URI。

查询的Projection:如果是混合查询或音视频,则查询出下列中所有的字段,而对于图片则没有时长(duration)字段。

    private static final String[] ITEM_PROJECTION = {
            MediaStore.MediaColumns._ID,
            MediaStore.MediaColumns.DATA,
            MediaStore.MediaColumns.MIME_TYPE,
            MediaStore.Video.Media.DURATION};

查询的Selection:和文件夹类似的是,混合查询,所有的图片,音视频的列表内也是使用mimetyp和size查询,而对于指定的文件夹内的图片则需要加上bucket_id这个条件。

排序order by:同样使用date_modified desc。

这样就查询出了所有的item,这次 不再对cursor进行过多的处理,只需要直接显示即可,如果用RecyclerView来显示则需要参考CursorAdapter来构建一个类似的RecyclerViewCursorAdapter进行显示。

这样就完成了查询的功能。

中篇就降到这里,最后一篇再讲图片和音视频的显示及预览。

发布了53 篇原创文章 · 获赞 17 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/jklwan/article/details/100752303