示例#1
0
        private void DrawScale(Canvas canvas)
        {
            canvas.Save(SaveFlags.Matrix);
            // On canvas, North is 0 degrees, East is 90 degrees, South is 180 etc.
            // We start the scale somewhere South-West so we need to first rotate the canvas.
            canvas.Rotate(mScaleRotation, 0.5f, 0.5f);

            int totalTicks = mDivisions * mSubdivisions + 1;

            for (int i = 0; i < totalTicks; i++)
            {
                float y1 = mScaleRect.Top;
                float y2 = y1 + 0.015f; // height of division
                float y3 = y1 + 0.045f; // height of subdivision

                float value = GetValueForTick(i);
                Paint paint = GetRangePaint(value);
                float mod   = value % mDivisionValue;

                if ((Math.Abs(mod - 0) < 0.001) || (Math.Abs(mod - mDivisionValue) < 0.001))
                {
                    // Draw a division tick
                    canvas.DrawLine(0.5f, y1, 0.5f, y3, paint);
                    // Draw the text 0.15 away from the division tick
                    DrawTextOnCanvasWithMagnifier(canvas, ValueString(value), 0.5f, y3 + 0.045f, paint);
                }
                else
                {
                    // Draw a subdivision tick
                    canvas.DrawLine(0.5f, y1, 0.5f, y2, paint);
                }
                canvas.Rotate(mSubdivisionAngle, 0.5f, 0.5f);
            }
            canvas.Restore();
        }
示例#2
0
        private void ComputeCurrentValue()
        {
            if (!(Math.Abs(mCurrentValue - mTargetValue) > 0.01f))
            {
                return;
            }

            if (-1 != mNeedleLastMoved)
            {
                float time      = (JavaSystem.CurrentTimeMillis() - mNeedleLastMoved) / 1000.0f;
                float direction = Math.Signum(mNeedleVelocity);
                if (Math.Abs(mNeedleVelocity) < 90.0f)
                {
                    mNeedleAcceleration = 5.0f * (mTargetValue - mCurrentValue);
                }
                else
                {
                    mNeedleAcceleration = 0.0f;
                }

                mNeedleAcceleration = 5.0f * (mTargetValue - mCurrentValue);
                mCurrentValue      += mNeedleVelocity * time;
                mNeedleVelocity    += mNeedleAcceleration * time;

                if ((mTargetValue - mCurrentValue) * direction < 0.01f * direction)
                {
                    mCurrentValue       = mTargetValue;
                    mNeedleVelocity     = 0.0f;
                    mNeedleAcceleration = 0.0f;
                    mNeedleLastMoved    = -1L;
                }
                else
                {
                    mNeedleLastMoved = JavaSystem.CurrentTimeMillis();
                }

                Invalidate();
            }
            else
            {
                mNeedleLastMoved = JavaSystem.CurrentTimeMillis();
                ComputeCurrentValue();
            }
        }
        public override bool OnTouchEvent(MotionEvent ev)
        {
            if (mIsVerbose)
            {
                Log.Verbose(TAG, "onTouchEvent: " + ((int)ev.Action & MotionEventCompat.ActionMask));
            }

            if (mVelocityTracker == null)
            {
                mVelocityTracker = VelocityTracker.Obtain();
            }
            mVelocityTracker.AddMovement(ev);

            var action = ev.Action;

            switch ((int)action & MotionEventCompat.ActionMask)
            {
            case (int)MotionEventActions.Down:
                // If being flinged and user touches, stop the fling. isFinished
                // will be false if being flinged.
                if (!mScroller.IsFinished)
                {
                    mScroller.AbortAnimation();
                }

                // Remember where the motion event started
                mDownMotionX     = ev.GetX();
                mDownMotionY     = ev.GetY();
                mDownScrollX     = ScrollX;
                mActivePointerId = MotionEventCompat.GetPointerId(ev, 0);
                break;

            case (int)MotionEventActions.Move:
                if (mIsVerbose)
                {
                    Log.Verbose(TAG, "mTouchState=" + mTouchState);
                }

                if (mTouchState == TOUCH_STATE_SCROLLING)
                {
                    // Scroll to follow the motion event
                    int   pointerIndex = MotionEventCompat.FindPointerIndex(ev, mActivePointerId);
                    float x            = MotionEventCompat.GetX(ev, pointerIndex);

                    View lastChild  = GetChildAt(ChildCount - 1);
                    int  maxScrollX = lastChild.Right - Width;
                    ScrollTo(Math.Max(0, Math.Min(maxScrollX,
                                                  (int)(mDownScrollX + mDownMotionX - x
                                                        ))), 0);
                    if (mOnScrollListener != null)
                    {
                        mOnScrollListener.OnScroll(GetCurrentScreenFraction());
                    }
                }
                else if (mTouchState == TOUCH_STATE_REST)
                {
                    if (mLocked)
                    {
                        // we're locked on the current screen, don't allow moving
                        break;
                    }

                    /*
                     * Locally do absolute value. mLastMotionX is set to the y value
                     * of the down event.
                     */
                    int   pointerIndex = MotionEventCompat.FindPointerIndex(ev, mActivePointerId);
                    float x            = MotionEventCompat.GetX(ev, pointerIndex);
                    float y            = MotionEventCompat.GetY(ev, pointerIndex);
                    int   xDiff        = (int)Math.Abs(x - mDownMotionX);
                    int   yDiff        = (int)Math.Abs(y - mDownMotionY);

                    bool xPaged = xDiff > mPagingTouchSlop;
                    bool xMoved = xDiff > mTouchSlop;
                    bool yMoved = yDiff > mTouchSlop;

                    if (xMoved || yMoved)
                    {
                        if (xPaged)
                        {
                            // Scroll if the user moved far enough along the X axis
                            mTouchState = TOUCH_STATE_SCROLLING;
                        }
                        // Either way, cancel any pending longpress
                        if (mAllowLongPress)
                        {
                            mAllowLongPress = false;
                            // Try canceling the long press. It could also have been scheduled
                            // by a distant descendant, so use the mAllowLongPress flag to block
                            // everything
                            View currentScreen = GetScreenAt(mCurrentScreen);
                            if (currentScreen != null)
                            {
                                currentScreen.CancelLongPress();
                            }
                        }
                    }
                }
                break;

            case (int)MotionEventActions.Up:
                if (mTouchState == TOUCH_STATE_SCROLLING)
                {
                    int             activePointerId = mActivePointerId;
                    int             pointerIndex    = MotionEventCompat.FindPointerIndex(ev, activePointerId);
                    float           x = MotionEventCompat.GetX(ev, pointerIndex);
                    VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.ComputeCurrentVelocity(1000, mMaximumVelocity);
                    //TODO(minsdk8): int velocityX = (int) MotionEventUtils.getXVelocity(velocityTracker, activePointerId);
                    int  velocityX = (int)velocityTracker.XVelocity;
                    bool isFling   = Math.Abs(mDownMotionX - x) > MIN_LENGTH_FOR_FLING;

                    float scrolledPos = GetCurrentScreenFraction();
                    int   whichScreen = Math.Round(scrolledPos);

                    if (isFling && mIsVerbose)
                    {
                        Log.Verbose(TAG, "isFling, whichScreen=" + whichScreen
                                    + " scrolledPos=" + scrolledPos
                                    + " mCurrentScreen=" + mCurrentScreen
                                    + " velocityX=" + velocityX);
                    }
                    if (isFling && velocityX > SNAP_VELOCITY && mCurrentScreen > 0)
                    {
                        // Fling hard enough to move left
                        // Don't fling across more than one screen at a time.
                        int bound = scrolledPos <= whichScreen ?
                                    mCurrentScreen - 1 : mCurrentScreen;
                        SnapToScreen(Math.Min(whichScreen, bound));
                    }
                    else if (isFling && velocityX < -SNAP_VELOCITY &&
                             mCurrentScreen < ChildCount - 1)
                    {
                        // Fling hard enough to move right
                        // Don't fling across more than one screen at a time.
                        int bound = scrolledPos >= whichScreen ?
                                    mCurrentScreen + 1 : mCurrentScreen;
                        SnapToScreen(Math.Max(whichScreen, bound));
                    }
                    else
                    {
                        SnapToDestination();
                    }
                }
                else
                {
                    PerformClick();
                }
                mTouchState      = TOUCH_STATE_REST;
                mActivePointerId = INVALID_POINTER;
                // Can't do this -> // Intentially fall through to cancel
                mTouchState      = TOUCH_STATE_REST;
                mActivePointerId = INVALID_POINTER;
                if (mVelocityTracker != null)
                {
                    mVelocityTracker.Recycle();
                    mVelocityTracker = null;
                }
                break;

            case (int)MotionEventActions.Cancel:
                mTouchState      = TOUCH_STATE_REST;
                mActivePointerId = INVALID_POINTER;
                if (mVelocityTracker != null)
                {
                    mVelocityTracker.Recycle();
                    mVelocityTracker = null;
                }
                break;


            case (int)MotionEventCompat.ActionPointerUp:
                OnSecondaryPointerUp(ev);
                break;
            }

            return(true);
        }
示例#4
0
        public bool OnTouch(View view, MotionEvent motionEvent)
        {
            if (view != LastTouchedView)
            {
                Count           = 0;
                LastTouchedView = view;
            }

            if (motionEvent.Action == MotionEventActions.Up)
            {
                Count = 0;
                return(true);
            }

            if (Count < 2)
            {
                if (Count == 0)
                {
                    HasCloned = false;
                    FirstX    = motionEvent.GetX();
                    FirstY    = motionEvent.GetY();
                }

                Count++;
                return(true);
            }

            float dX = Math.Abs(motionEvent.GetX() - FirstX);
            float dY = Math.Abs(motionEvent.GetY() - FirstY);

            if (LastTouchedView.Parent is RecyclerView && (dX > dY) ||
                LastTouchedView.Parent is LinearLayout && dY > dX)
            {
                return(false);
            }

            if (view is RecyclerBlockView recyclerBlockView)
            {
                if (!HasCloned)
                {
                    // OnTouchListener is set in DragAction.OnDrop, and OnDragListener doesn't need to be set on the BlockView, as it's set in the ctor of ContainerBlockView !
                    LastClonedRbv = recyclerBlockView.Clone();
                    HasCloned     = true;
                }

                view = LastClonedRbv;
            }

            SaveViewPosition(view);

            ClipData clipData = new ClipData("dragged",
                                             new[] { ClipDescription.MimetypeTextPlain },
                                             new ClipData.Item("dragged"));


            if (view.StartDragAndDrop(clipData, new View.DragShadowBuilder(LastTouchedView), view, 0))
            {
                view.Visibility = ViewStates.Invisible;
            }
            else
            {
                if (LastTouchedView is RecyclerBlockView blockView)
                {
                    blockView.RemoveCloneInstance();
                }
            }

            return(true);
        }