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"?>
希望对有需要的人有帮助~