我是靠谱客的博主 激动心情,最近开发中收集的这篇文章主要介绍photoView中的fling事件分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

上一篇大概介绍了photoView的touch事件的传递,写的惨不忍睹,也比较简单,想要理解还是得去看源码;这一篇主要介绍下其中对fling事件的分析,顾名思义,就是当图片放大之后,单手快速一滑动,图片会有个惯性移动,而在photoView中,就是在onFling方法中处理的。

源码长这样:
 @Override
    public void onFling(float startX, float startY,float velocityX,float velocityY) {
        ImageView imageView = getImageView();
        mCurrentFlingRunnable = new FlingRunnable(imageView.getContext());
                mCurrentFlingRunnable.fling(getImageViewWidth(imageView),getImageViewHeight(imageView), (int) velocityX, (int) velocityY);

     imageView.post(mCurrentFlingRunnable);
    }

我们可以看到这里有个FlingRunnable这个东西,目测就是执行那个惯性运动的动画。详细一看

public FlingRunnable(Context context) {
            mScroller = ScrollerProxy.getScroller(context);
        }

构造里面有个scoller,应该就是靠他执行滚动的事件,首先执行了该runnable里的fling方法:

public void fling(int viewWidth, int viewHeight, int velocityX,
                          int velocityY) {
            final RectF rect = getDisplayRect();
            if (null == rect) {
                return;
            }
            final int startX = Math.round(-rect.left);
            final int minX, maxX, minY, maxY;

            if (viewWidth < rect.width()) {
                minX = 0;
                maxX = Math.round(rect.width() - viewWidth);
            } else {
                minX = maxX = startX;
            }

            final int startY = Math.round(-rect.top);
            if (viewHeight < rect.height()) {
                minY = 0;
                maxY = Math.round(rect.height() - viewHeight);
            } else {
                minY = maxY = startY;
            }

            mCurrentX = startX;
            mCurrentY = startY;

            if (startX != maxX || startY != maxY) {
                mScroller.fling(startX, startY, velocityX, velocityY, minX,
                        maxX, minY, maxY, 0, 0);
            }
        }

这里面处理了我们可以fling的范围,设置在我们scroller里面,比如他的x范围,通过放大后的RectF 和实际imageview的大小算出范围。

public void run() {
            if (mScroller.isFinished()) {
                return; // remaining post that should not be handled
            }

            ImageView imageView = getImageView();
            if (null != imageView && mScroller.computeScrollOffset()) {

                final int newX = mScroller.getCurrX();
                final int newY = mScroller.getCurrY();

                if (DEBUG) {
                    LogManager.getLogger().d(
                            LOG_TAG,
                            "fling run(). CurrentX:" + mCurrentX + " CurrentY:"
                                    + mCurrentY + " NewX:" + newX + " NewY:"
                                    + newY);
                }

                mSuppMatrix.postTranslate(mCurrentX - newX, mCurrentY - newY);
                setImageViewMatrix(getDrawMatrix());

                mCurrentX = newX;
                mCurrentY = newY;

                // Post On animation
                Compat.postOnAnimation(imageView, this);
            }

最后执行runnable这个线程,这里用到了scroller里的知识,不会的同学自行百度;通过:

mSuppMatrix.postTranslate(mCurrentX - newX, mCurrentY - newY);
                setImageViewMatrix(getDrawMatrix());

这俩句不断设置新的matrix,声明重绘,我们还看到这里有个

Compat.postOnAnimation(imageView, this);

这里其实是个递归调用,不断调用该runnable,达到连续的绘制过程,代码如下:

public class Compat {

    private static final int SIXTY_FPS_INTERVAL = 1000 / 60;

    public static void postOnAnimation(View view, Runnable runnable) {
        if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
            postOnAnimationJellyBean(view, runnable);
        } else {
            view.postDelayed(runnable, SIXTY_FPS_INTERVAL);
        }
    }

    @TargetApi(16)
    private static void postOnAnimationJellyBean(View view, Runnable runnable) {
        view.postOnAnimation(runnable);
    }

最后会到view.postOnAnimation(runnable)这句,又重新调用了我们的runnable,知道滚动完毕。

最后

以上就是激动心情为你收集整理的photoView中的fling事件分析的全部内容,希望文章能够帮你解决photoView中的fling事件分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部