Android 仿相册列表-时间头部的UI效果


Android 仿相册列表-时间头部的UI效果

<异空间>项目技术分享系列——相册列表的时间头部方案

先上效果图(比较简单的效果,可继续扩展实现),以下代码使用Kotlin语言编写

项目使用了CymChad/BaseRecyclerViewAdapterHelper的 sectionAdapter类 ,其他Adapter可以参考参考。

按照BRAVH的API文档,对实体类要实现 SectionEntity 接口,然后在isHeader方法内,通过这个对象的一些属性判断出这个item是否已经被用来构建头部Section的布局

data class ImageFile(
    val lastModifyTime:String , val path:String , 
    val size : String  ,val file : File?) : SectionEntity {

    override val isHeader: Boolean
        get() {
            //通过此对象的一些属性,判断当前对象是否为特殊的Section item
            return ""==path && size == "" && file == null
        }

}

接下来是第二步,对Adapter动刀,继承BaseSectionQuickAdapter,实现必要的方法,根据实体类实现的isHeader方法,判断要执行convertHeader还是convert构建哪个布局。

class GalleryTimeLineAdapter(
    layoutResId: Int = R.layout.item_picture_gallery, //实际的item布局
    sectionHeadResId: Int = R.layout.item_section_header_gallery,//section头部布局
    data: MutableList ?
) : BaseSectionQuickAdapter(sectionHeadResId,layoutResId , data) {
    /**
     * 构造方法里, super()必须设置 header layout
     * data可有可无
     */
    init {
        // 设置普通item布局(如果item类型只有一种,使用此方法)
        setNormalLayout(layoutResId)
        // 注册需要点击的子view id
        addChildClickViewIds(R.id.btn_operate_section_gallery)
    }

    /**
     * 设置header数据
     */
    protected override fun convertHeader(
        @NotNull helper: BaseViewHolder,
        @NotNull item: ImageFile) {
        
          helper.setText(R.id.tv_modify_time_section_gallery , item.lastModifyTime )
    }

    protected override fun convert(@NotNull holder: BaseViewHolder, item: ImageFile) {
        //设置item数据
        Glide.with(context)
            .asDrawable()
            .centerCrop()
            .load(item.file)
            .into(holder.getView(R.id.iv_item_thumbnail_gallery))
    }
    
}

处理数据源 ,将从本地获取到的List< File > 经过时间排序,在每个不同日期前增加一个带有特殊属性的ImageFile对象作为头部添加进imgFileList, 处理完成后再返回给RecyclerView加载

 //待处理返回的目标图片文件ImageFile列表
 val imgFileList = mutableListOf()
 //从本地获取到的类型为图片的 file列表
 val rawImgFileList = EncryptFileUtil.getFilesInImageEncryptDir(imgDirNa
 if (rawImgFileList.isNotEmpty()) {
     //对所有文件排序,按照最新时间递减下去
     rawImgFileList.sortWith(Comparator { img1, img2 ->
         img2.lastModified().compareTo(img1.lastModified())
     })
     val dateFormat = TimeUtils.getSafeDateFormat("YYYY年MM月dd日")
     //首个分段头部时间
     val firstTimeSection = rawImgFileList[0].lastModified()
     //分段头部日期字符串
     var sectionDate = TimeUtils.millis2String(firstTimeSection, dateFor
     //以第一个图片文件的日期作为首个头部,添加进图片文件列表
     var imgSection = ImageFile(sectionDate, "", "", null)
     imgFileList.add(imgSection)
     rawImgFileList.forEach { rawFile ->
         val imgFile = ImageFile(
             TimeUtils.millis2String(rawFile.lastModified()),
             rawFile.absolutePath,
             FileUtils.getSize(rawFile),
             rawFile
         )
         //以年月日的形式与当前已添加的头部进行比较
         val rawFileDate = TimeUtils.millis2String(rawFile.lastModified(
         if (sectionDate != rawFileDate) {
             //发现有不相同的日期的图片文件,则需要添加新的"头部"了
             sectionDate = rawFileDate
             imgSection = ImageFile(sectionDate, "", "", null)
             imgFileList.add(imgSection)
         }
         //当确保头部已经添加好后,再添加
         imgFileList.add(imgFile)
     }
 }

图片item布局参考:

<?xml version="1.0" encoding="utf-8"?>


    
    


头部参考布局

<?xml version="1.0" encoding="utf-8"?>


    

    

希望对有需要的人有帮助~