大图浏览几乎是App必备功能,由于通常列表展现的图片,考虑到性能,速度以及服务器带宽的问题,都是压缩过的缩略图。若是用户想看详细的大图,则须要点击图片进入大图浏览界面。java
大图浏览界面怎么作?git
粗略的咱们能够用一个对话框,里面放ViewPager,而后缩放用PhotoView。之前我也是这么干的。但这么作是不符合Material Design设计的,由于界面之间的切换太突兀,没有如丝般顺滑的过渡效果。github
来看下我实现的效果:服务器
以前在Android端目前我以为大图浏览体验最好的就是掘金App的效果,我这个应该能够媲美掘金的效果了。真实体验你会发现,可能比掘金的更流畅,更丝滑。ide
原理上有几个点:性能
图片之间的过渡是指小图到大图的过渡,中间没有任何的跳跃变化,须要是丝滑而天然的过渡。这个要考虑的使用者的ImageView有多是各类的ScaleType。对于任意的ScaleType如何实现完美的过渡呢?spa
答案只有一个,就是: Martirx。设计
由于不管ImageView的ScaleType是什么,最终都会计算出一个DrawMartix,它表示图片的像素矩阵。因此对Martix进行过渡才是正确的,这过程当中我探索了不少方案,好比宽高,手动计算Martix。3d
至于具体怎么对Martix进行过渡,咱们能够很容易写出一个ValueAnimator,也能够用系统的ChangeImageTransform来作。我选择的是后者。具体看源码吧。code
界面之间的过渡,指的是从调用者的界面过渡到大图界面。这实际上是一个弹窗效果,它主要伴随着背景明暗的渐变,这个很容易实现。你能够用PopupWindow,Dialog,或者whatever。我是直接依靠XPopup(个人一个弹窗库)提供的弹窗实现。
从动图中能够看到,大图浏览能够经过点击关闭,也能够经过手势上下滑动关闭。可拖拽的容器实现起来并不难,能够本身操做TouchEvent,也能够用ViewDragHelper。我比较喜欢后者。核心的拖拽代码其实不超过50行。
单单拖拽很好作,可是涉及到ViewPager和里面的PhotoView就有点麻烦了。须要处理好跟ViewPager的滑动优先选择,还要PhotoView是否能够容许外界拖拽。更细节的东西能够看代码。
上面的效果,我直接内置在XPopup中,提供一个封装。使用起来也就是这样:
XPopup.get(getContext()).asImageViewer(imageView, position, list, new OnSrcViewUpdateListener() {
@Override
public void onSrcViewUpdate(ImageViewerPopupView popupView, int position) {
// 做用是当Pager切换了图片,须要更新源View
popupView.updateSrcView((ImageView) recyclerView.getChildAt(position));
}
}).show();
复制代码
具体使用请查看:github.com/li-xiaojun/…
最后:曾经的Android开发很难,为简化Android开发贡献一份小小的力量。