public void Run()
            {
                if (mScroller.IsFinished())
                {
                    return;                     // remaining post that should not be handled
                }
                ImageView imageView = photoViewAttacher.GetImageView();

                if (null != imageView && mScroller.ComputeScrollOffset())
                {
                    int newX = mScroller.GetCurrX();
                    int newY = mScroller.GetCurrY();
                    if (photoViewAttacher.DEBUG)
                    {
                        LogManager.GetLogger().d(
                            LOG_TAG,
                            "fling run(). CurrentX:" + mCurrentX + " CurrentY:"
                            + mCurrentY + " NewX:" + newX + " NewY:"
                            + newY);
                    }
                    photoViewAttacher.mSuppMatrix.PostTranslate(mCurrentX - newX, mCurrentY - newY);
                    photoViewAttacher.SetImageViewMatrix(photoViewAttacher.GetDrawMatrix());
                    mCurrentX = newX;
                    mCurrentY = newY;
                    Compat.PostOnAnimation(imageView, this);
                }
            }
            public void Run()
            {
                ImageView imageView = photoViewAttacher.GetImageView();

                if (imageView == null)
                {
                    return;
                }

                float t          = Interpolate();
                float scale      = mZoomStart + t * (mZoomEnd - mZoomStart);
                float deltaScale = scale / photoViewAttacher.GetScale();

                photoViewAttacher.mSuppMatrix.PostScale(deltaScale, deltaScale, mFocalX, mFocalY);
                photoViewAttacher.CheckAndDisplayMatrix();

                // We haven't hit our target scale yet, so post ourselves again
                if (t < 1f)
                {
                    Compat.PostOnAnimation(imageView, this);
                }
            }
        public override bool OnTouchEvent(MotionEvent ev)
        {
            MotionEventActions action = ev.Action;

            switch (action & MotionEventActions.Mask)
            {
            case MotionEventActions.Down:
                mActivePointerId = ev.GetPointerId(0);
                break;

            case MotionEventActions.Cancel:
            case MotionEventActions.Up:
                mActivePointerId = INVALID_POINTER_ID;
                break;

            case MotionEventActions.PointerUp:
                // Ignore deprecation, ACTION_POINTER_ID_MASK and
                // ACTION_POINTER_ID_SHIFT has same value and are deprecated
                // You can have either deprecation or lint target api warning
                int pointerIndex = Compat.GetPointerIndex(ev.Action);
                int pointerId    = ev.GetPointerId(pointerIndex);
                if (pointerId == mActivePointerId)
                {
                    // This was our active pointer going up. Choose a new
                    // active pointer and adjust accordingly.
                    int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    mActivePointerId = ev.GetPointerId(newPointerIndex);
                    mLastTouchX      = ev.GetX(newPointerIndex);
                    mLastTouchY      = ev.GetY(newPointerIndex);
                }
                break;
            }

            mActivePointerIndex = ev
                                  .FindPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId
                                        : 0);
            return(base.OnTouchEvent(ev));
        }