前言

大图浏览几乎是 App 必备功能,因为一般列表展示的图片,考虑到性能,速度以及服务器带宽的问题,都是压缩过的缩略图。如果用户想看详细的大图,则需要点击图片进入大图浏览界面。

大图浏览界面怎么做?

粗略的我们可以用一个对话框,里面放 ViewPager,然后缩放用 PhotoView。以前我也是这么干的。但这么做是不符合 Material Design 设计的,因为界面之间的切换太突兀,没有如丝般顺滑的过渡效果。

无图言 Diao

来看下我实现的效果:

之前在 Android 端目前我觉得大图浏览体验最好的就是掘金 App 的效果,我这个应该可以媲美掘金的效果了。真实体验你会发现,可能比掘金的更流畅,更丝滑。

原理分析

原理上有几个点:

  • 图片之间的过渡

图片之间的过渡是指小图到大图的过渡,中间没有任何的跳跃变化,需要是丝滑而自然的过渡。这个要考虑的使用者的 ImageView 有可能是各种的 ScaleType。对于任意的 ScaleType 如何实现完美的过渡呢?

答案只有一个,就是: Martirx。

因为无论 ImageView 的 ScaleType 是什么,最终都会计算出一个 DrawMartix,它表示图片的像素矩阵。所以对 Martix 进行过渡才是正确的,这过程中我探索了很多方案,比如宽高,手动计算 Martix。

至于具体怎么对 Martix 进行过渡,我们可以很容易写出一个 ValueAnimator,也可以用系统的 ChangeImageTransform 来做。我选择的是后者。具体看源码吧。

  • 界面之间的过渡

界面之间的过渡,指的是从调用者的界面过渡到大图界面。这其实是一个弹窗效果,它主要伴随着背景明暗的渐变,这个很容易实现。你可以用 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 开发贡献一份小小的力量。

  • Android

    开放手机联盟(一个由 30 多家科技公司和手机公司组成的团体)已开发出 Android,Android 是第一个完整、开放、免费的手机平台。

    293 引用
感谢    赞同    分享    收藏    关注    反对    举报    ...