Imageviewer
提供查看缩略视图到原视图的无缝过渡转变的视觉效果,优雅的浏览普通图、长图、动图.
主要功能
- 过渡动画 缩略图到大图或大图到缩略图时提供无缝衔接动画
- 浏览手势 浏览大图时可使用常势操用手.如缩放图片等.(PhotoView)
- 超大图 图片区块加载.避免OOM(SubsamplingScaleImageView)
- Video 支持Video加载 (SimpleExoPlayer)
- 拖拽关闭 对大图进行上/下滑操作退出浏览.
- 数据分页加载 在浏览大图的情况下异步加载百万数据.
- 自定义UI 对预览页的UI元素自定义追加
使用
implementation 'com.github.iielse:imageviewer:2.1.2'
val builder = ImageViewerBuilder(
context = this,
initKey = photo.id, // 用于定位被点击缩略图变化大图后初始化所在位置.以此来执行过渡动画.
dataProvider = MyDataProvider(), // 浏览数据源的提供者.支持一次性给全数据或分页加载.
imageLoader = MyImageLoader(), // 实现对数据源的加载.支持自定义加载数据类型,加载方案
transformer = MyTransformer() // 以photoId为标示,设置过渡动画的'配对'.
)
builder.setVHCustomizer(MyCustomViewHolderUI()) // 自定义每一页上的UI.比如可显示图片的更多信息.提供存储分享等更多功能等
builder.setOverlayCustomizer(MyCustomIndicatorUI()) // 自定义'覆盖(最上)层'上的UI.比如添加指示器等
builder.setViewerCallback(MyViewerStateChangedListener()) // 监听viewer的各种状态变化.包括页面的切换.以及过渡动画的执行状态
builder.show()
主要接口
class MyImageLoader : ImageLoader {
/**
* 根据自身photo数据加载图片.可以使用其它图片加载框架.
*/
override fun load(view: ImageView, data: Photo, viewHolder: RecyclerView.ViewHolder) {
val it = (data as? MyData?)?.url ?: return
Glide.with(view).load(it)
.override(view.width, view.height)
.placeholder(view.drawable)
.into(view)
}
/**
* 根据自身photo数据加载超大图.subsamplingView数据源需要先将内容完整下载到本地.需要注意生命周期
*/
override fun load(subsamplingView: SubsamplingScaleImageView, data: Photo, viewHolder: RecyclerView.ViewHolder) {
val it = (data as? MyData?)?.url ?: return
subsamplingDownloadRequest(it)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe { findLoadingView(viewHolder)?.visibility = View.VISIBLE }
.doFinally { findLoadingView(viewHolder)?.visibility = View.GONE }
.doOnNext { subsamplingView.setImage(ImageSource.uri(Uri.fromFile(it))) }
.doOnError { toast(it.message) }
.subscribe().bindLifecycle(subsamplingView)
}
private fun subsamplingDownloadRequest(url: String): Observable<File> {
return Observable.create {
try {
it.onNext(Glide.with(appContext()).downloadOnly().load(url).submit().get())
it.onComplete()
} catch (e: java.lang.Exception) {
if (!it.isDisposed) it.onError(e)
}
}
}
private fun findLoadingView(viewHolder: RecyclerView.ViewHolder): View? {
return viewHolder.itemView.findViewById<ProgressBar>(R.id.loadingView)
}
}
略.
其它说明
已适配RTL布局 Video加载请参考demo demo可运行.demo代码已重构.具备良好可读性.放心食用