记一次相册重构
相册重构背景
旧相册现状:
- 多种相册耦合严重,难以维护迭代
- 入口参数混乱,容易出错
- 分页多次扫描,多次查询
- 数据结构不合理,数据源管理较多
- 扫描入口调用较多,界面退出扫描未及时终止
相册入口
class Picker {
companion object{
const val allTag = "全部"
/**
* 普通选择器
*/
@JvmStatic
fun basic() = BasicPicker()
/**
* 创作模板选择器
*/
@JvmStatic
fun creation() = CreationPicker()
/**
* AI模板选择器
*/
@JvmStatic
fun ai() = AiPicker()
}
}
//启动示例代码,可链式设置常见参数通过回调直接返回
Picker.basic().setMax(1).setType(PickType.IMG).start(medias -> {
});
相册选取的配置选项
class BasicPicker : BasePicker() {
/**
* 设置类型,默认图片 + 视频
*/
fun setType(type: PickType): BasicPicker {
config.type = type
return this
}
/**
* 是否保留选择页面
*/
fun setKeep(value:Boolean): BasicPicker{
config.keep = value
return this
}
/**
* 设置最小选择数量
*/
fun setMin(value:Int): BasicPicker{
config.minPick = value
return this
}
/**
* 设置最大选择数量
*/
fun setMax(value:Int): BasicPicker{
config.maxPick = value
return this
}
/**
* 设置自定义检查器(其他关于选取的限制条件会失效)
*/
fun setChecker(clazz:Class<out AbsBaseChecker>): BasicPicker{
config.checker = clazz
return this
}
/**
* 设置选取提示文案
*/
fun setPickTip(value:String): BasicPicker{
config.pickTip = value
return this
}
/**
* 开始跳转选择
*/
fun start(call: PickCall){
[config.call](http://config.call) = call
[AbsBasePickAct.data](http://AbsBasePickAct.data) = config
ActivityUtils.startActivity(BasicPickAct::[class.java](http://class.java))
}
}
<br/>
相册展示及扫描流程(这里只列举基础相册)
- 入口设置选项,并生成配置一个配置对象 PickConfig,跳转并传递到展示页(部分代码)
class PickConfig {
//最少数量
var minPick = 1
//最大数量
var maxPick = -1
//最小时长(视频,毫秒)
var limit: Int = Int.MAX_VALUE
//类型,默认 图片+视频
var type = PickType.BOTH
//选择完是否保留页面
var keep = false
//回调
var call: PickCall? = null
//选取检查器,可自定义
var checker: Class<out AbsBaseChecker> = BasicChecker::[class.java](http://class.java)
//选取文字提示
var pickTip: String = ""
//note 基础相册
//选择结果
val selList = ArrayList<Media>()
}
- 展示页如BasicPickAct 继承 AbsBasePickAct。如配置读取,执行扫描器,封装相册用到的通用行为:
/**
* 开始扫描
*/
abstract fun startScan()
/**
* 目录更新通知
*/
abstract fun notifyDir()
/**
* 分页更新通知
*/
abstract fun notifyPage()
/**
* 选择文件夹更新
*/
abstract fun pickDir(dir: MediaDir)
/**
* 选择变化(tab) 选中、取消
*/
abstract fun selectChange()
/**
* 移除选中(底部)
*/
abstract fun selectRemove()
/**
* 预览选中状态更新
*/
abstract fun preViewUpdate(media: Media)
/**
* 回收
*/
abstract fun destroy()
- 相册扫描–PickScanner
其主要功能是相册扫描,扫描图像跟视频,并根据文件夹名称进行分类,还有通知功能
扫描过程中,PickScanner会根据一定的数量进行分页通知,以通知UI及时更新
这里扫描用到 lifecycleScope管理生命周期,会在界面finish的时候提前终止扫描,避免性能浪费
4. 选择器–BasicChecker,可在Config.checker进行配置
类似Okhttp拦截器原理,接入方可继承AbsBaseChecker,干预 图片/视频是否可以被选取的状态,
替换check后,默认的可选配置会失效,需要自行根据配置处理
5. 图片/视频Tab 展示页 BasicMediaTabFrag,负责具体资源展示,还有选取,预览等操作
BasicMediaTabAdapter适配器是其核心代码,第4点的BasicChecker在此处判断选取及展示