public override void ComputeScroll()
        {
            if (!_dragHelper.ContinueSettling(true))
            {
                return;
            }

            if (!_canSlide)
            {
                _dragHelper.Abort();
                return;
            }

            ViewCompat.PostInvalidateOnAnimation(this);
        }
Пример #2
0
        private void IncrementSnapback()
        {
            if (scroller.IsFinished)
            {
                return;
            }

            var more = scroller.ComputeScrollOffset();

            Header.OffsetTopAndBottom(current_scroll_y - scroller.CurrY);
            ((View)ContentView).OffsetTopAndBottom(current_scroll_y - scroller.CurrY);
            current_scroll_y = scroller.CurrY;

            if (more)
            {
                ViewCompat.PostInvalidateOnAnimation(this);
            }
        }
Пример #3
0
        private bool SmoothSlideTo(float slideOffset)
        {
            if (!_canSlide)
            {
                return(false);
            }

            var y = _isSlidingUp
                ? (int)(SlidingTop + slideOffset * _slideRange)
                : (int)(SlidingTop - slideOffset * _slideRange);

            if (!_dragHelper.SmoothSlideViewTo(_slideableView, _slideableView.Left, y))
            {
                return(false);
            }

            SetAllChildrenVisible();
            ViewCompat.PostInvalidateOnAnimation(this);
            return(true);
        }
Пример #4
0
        /**
         * Close the panel to hide the secondary view
         * @param animation true to animate the close motion. {@link SwipeListener} won't be
         *                  called if is animation is false.
         */
        public void close(bool animation)
        {
            CoreUtility.ExecuteMethod("close", delegate()
            {
                mIsOpenBeforeInit = false;
                mAborted          = false;

                if (animation)
                {
                    mState = STATE_CLOSING;
                    mDragHelper.SmoothSlideViewTo(mMainView, mRectMainClose.Left, mRectMainClose.Top);

                    if (mDragStateChangeListener != null)
                    {
                        mDragStateChangeListener.onDragStateChanged(mState);
                    }
                }
                else
                {
                    mState = STATE_CLOSE;
                    mDragHelper.Abort();

                    mMainView.Layout(
                        mRectMainClose.Left,
                        mRectMainClose.Top,
                        mRectMainClose.Right,
                        mRectMainClose.Bottom
                        );

                    mSecondaryView.Layout(
                        mRectSecClose.Left,
                        mRectSecClose.Top,
                        mRectSecClose.Right,
                        mRectSecClose.Bottom
                        );
                }

                ViewCompat.PostInvalidateOnAnimation(this);
            });
        }
Пример #5
0
            public override void OnViewPositionChanged(View changedView, int left, int top, int dx, int dy)
            {
                base.OnViewPositionChanged(changedView, left, top, dx, dy);
                if (_layout.mMode == MODE_SAME_LEVEL)
                {
                    if (_layout.mDragEdge == DRAG_EDGE_LEFT || _layout.mDragEdge == DRAG_EDGE_RIGHT)
                    {
                        _layout.mSecondaryView.OffsetLeftAndRight(dx);
                    }
                    else
                    {
                        _layout.mSecondaryView.OffsetTopAndBottom(dy);
                    }
                }

                bool isMoved = (_layout.mMainView.Left != _layout.mLastMainLeft) || (_layout.mMainView.Top != _layout.mLastMainTop);

                if (_layout.mSwipeListener != null && isMoved)
                {
                    if (_layout.mMainView.Left == _layout.mRectMainClose.Left && _layout.mMainView.Top == _layout.mRectMainClose.Top)
                    {
                        _layout.mSwipeListener.onClosed(_layout);
                    }
                    else if (_layout.mMainView.Left == _layout.mRectMainOpen.Left && _layout.mMainView.Top == _layout.mRectMainOpen.Top)
                    {
                        _layout.mSwipeListener.onOpened(_layout);
                    }
                    else
                    {
                        _layout.mSwipeListener.onSlide(_layout, getSlideOffset());
                    }
                }

                _layout.mLastMainLeft = _layout.mMainView.Left;
                _layout.mLastMainTop  = _layout.mMainView.Top;
                ViewCompat.PostInvalidateOnAnimation(_layout);
            }
Пример #6
0
        public override bool OnTouchEvent(MotionEvent e)
        {
            if (!IsPullEnabled)
            {
                return(base.OnTouchEvent(e));
            }

            if (null == ContentView)
            {
                return(base.OnTouchEvent(e));
            }

            if (ContentView is AbsListView && ((AbsListView)ContentView).FastScrollEnabled)
            {
                // An adimittedly crude way to determine if touch is in fast scroll, but
                // should accomplish the goal of not displaying ptr header.
                // This is crude because there is not a definitive way to determine
                // a) if the fast scroller is visible or
                // b) the width of the scroller
                if (Resources.DisplayMetrics.WidthPixels - e.RawX < fastscroll_thumb_width)
                {
                    return(false); // let the list view handle this
                }
            }

            switch (e.ActionMasked)
            {
            case MotionEventActions.Down:
                last_touch_y = ContentView.IsAtTop ? (int)e.RawY : -1;
                if (!ContentView.IsAtTop)
                {
                    send_down_event = false;     // because this event will reach the ContentView
                }
                else
                {
                    should_send_down_before_up = true;
                }
                return(ContentView.IsAtTop);

            case MotionEventActions.Move:
                if (did_steal_event_stream && current_scroll_y >= 0)
                {
                    if (send_down_event)
                    {
                        did_steal_event_stream        = false;
                        send_down_event               = false;
                        ContentView.IgnoreTouchEvents = false;
                        SendFakeEvent(e, MotionEventActions.Down);
                    }
                    return(true);
                }

                if (last_touch_y == -1)
                {
                    last_touch_y = (int)e.RawY;
                    return(true);
                }

                var y_delta = last_touch_y - (int)e.RawY;
                last_touch_y = (int)e.RawY;

                bool isMovingUp = y_delta > 0;
                if (isMovingUp && current_scroll_y >= 0 || !ContentView.IsAtTop)
                {
                    should_send_down_before_up = false;
                    ContentView.ForceHandleTouchEvent(e);
                    return(true);
                }

                if (ContentView.IsAtTop)
                {
                    var new_scroll_to = isMovingUp ? (int)y_delta : (int)(y_delta * PullDownTensionFactor);
                    // see if this will fully hide the header
                    if (current_scroll_y < 0 && current_scroll_y + new_scroll_to > 0)
                    {
                        // only scroll enough to hide the header
                        new_scroll_to = -current_scroll_y;
                    }

                    current_scroll_y += new_scroll_to;

                    Header.OffsetTopAndBottom(-new_scroll_to);
                    ((View)ContentView).OffsetTopAndBottom(-new_scroll_to);
                    ViewCompat.PostInvalidateOnAnimation(this);

                    if (current_scroll_y == 0)
                    {
                        ContentView.IgnoreTouchEvents = false;
                        return(true);
                    }
                    else
                    {
                        should_cancel_before_up    = true;
                        should_send_down_before_up = false;
                    }

                    if (Math.Abs(current_scroll_y) >= header_measured_height)
                    {
                        if (refresh_state != PullToRefresharpRefreshState.Refreshing)
                        {
                            SetPullDownIconProgress(1);
                            UpdateRefreshState(PullToRefresharpRefreshState.ReleaseToRefresh);
                        }
                    }
                    else
                    {
                        // Don't update anything if we are refreshing.
                        if (refresh_state != PullToRefresharpRefreshState.Refreshing)
                        {
                            SetPullDownIconProgress((float)Math.Abs(current_scroll_y) / (float)header_measured_height);
                            UpdateRefreshState(PullToRefresharpRefreshState.PullToRefresh);
                        }
                    }

                    return(true);
                }
                return(false);

            case MotionEventActions.Up:
                return(HandleUpEvent(e));
            }

            return(base.OnTouchEvent(e));
        }
            public void Draw(Canvas canvas)
            {
                var clipPath = new Path();

                clipPath.AddRoundRect(_bounds, _cornerRadius, _cornerRadius, Path.Direction.Cw);

                int width  = (int)_bounds.Width();
                int height = (int)_bounds.Height();
                int cx     = width / 2;
                int cy     = height / 2;

                bool drawTriggerWhileFinishing = false;
                int  restoreCount = canvas.Save();

                canvas.ClipPath(clipPath);

                if (_running || _finishTime > 0)
                {
                    long  now         = AnimationUtils.CurrentAnimationTimeMillis();
                    long  elapsed     = (now - _startTime) % ANIMATION_DURATION_MS;
                    long  iterations  = (now - _startTime) / ANIMATION_DURATION_MS;
                    float rawProgress = (elapsed / (ANIMATION_DURATION_MS / 100f));

                    if (!_running)
                    {
                        if ((now - _finishTime) >= FINISH_ANIMATION_DURATION_MS)
                        {
                            _finishTime = 0;
                            return;
                        }

                        // Otherwise, use a 0 opacity alpha layer to clear the animation
                        // from the inside out. This layer will prevent the circles from
                        // drawing within its bounds.
                        long  finishEplapsed = (now - _finishTime) % FINISH_ANIMATION_DURATION_MS;
                        float finishProgress = (finishEplapsed / (FINISH_ANIMATION_DURATION_MS / 100f));
                        float pct            = finishProgress / 100f;
                        float clearRadius    = width / 2 * _interpolator.GetInterpolation(pct);
                        _rectF.Set(cx - clearRadius, 0, cx + clearRadius, height);
                        canvas.SaveLayerAlpha(_rectF, 0, 0);

                        // Only draw the trigger if there is a space in the center of
                        // this refreshing view that needs to be filled in by the
                        // trigger. If the progress view is just still animating, let it
                        // continue animating.
                        drawTriggerWhileFinishing = true;
                    }

                    // First fill in with the last color that would have finished drawing.
                    if (iterations == 0)
                    {
                        canvas.DrawColor(ColorUtils.FromUint(_color1));
                    }
                    else
                    {
                        if (rawProgress >= 0 && rawProgress < 25)
                        {
                            canvas.DrawColor(ColorUtils.FromUint(_color4));
                        }
                        else if (rawProgress >= 25 && rawProgress < 50)
                        {
                            canvas.DrawColor(ColorUtils.FromUint(_color1));
                        }
                        else if (rawProgress >= 50 && rawProgress < 75)
                        {
                            canvas.DrawColor(ColorUtils.FromUint(_color2));
                        }
                        else
                        {
                            canvas.DrawColor(ColorUtils.FromUint(_color3));
                        }
                    }

                    // Then draw up to 4 overlapping concentric circles of varying radii, based on how far
                    // along we are in the cycle.
                    // progress 0-50 draw mColor2
                    // progress 25-75 draw mColor3
                    // progress 50-100 draw mColor4
                    // progress 75 (wrap to 25) draw mColor1
                    if (rawProgress >= 0 && rawProgress <= 25)
                    {
                        float pct = (rawProgress + 25) * 2 / 100f;
                        DrawCircle(canvas, cx, cy, _color1, pct);
                    }

                    if (rawProgress >= 0 && rawProgress <= 50)
                    {
                        float pct = ((rawProgress * 2) / 100f);
                        DrawCircle(canvas, cx, cy, _color2, pct);
                    }
                    if (rawProgress >= 25 && rawProgress <= 75)
                    {
                        float pct = (((rawProgress - 25) * 2) / 100f);
                        DrawCircle(canvas, cx, cy, _color3, pct);
                    }
                    if (rawProgress >= 50 && rawProgress <= 100)
                    {
                        float pct = (((rawProgress - 50) * 2) / 100f);
                        DrawCircle(canvas, cx, cy, _color4, pct);
                    }
                    if ((rawProgress >= 75 && rawProgress <= 100))
                    {
                        float pct = (((rawProgress - 75) * 2) / 100f);
                        DrawCircle(canvas, cx, cy, _color1, pct);
                    }

                    if (_triggerPercentage > 0 && drawTriggerWhileFinishing)
                    {
                        canvas.RestoreToCount(restoreCount);
                        restoreCount = canvas.Save();
                        canvas.ClipPath(clipPath);
                        DrawTrigger(canvas, cx, cy);
                    }

                    ViewCompat.PostInvalidateOnAnimation(_parent);
                }
                else if (_triggerPercentage > 0 && _triggerPercentage < 1.0)
                {
                    DrawTrigger(canvas, cx, cy);
                }

                canvas.RestoreToCount(restoreCount);
            }
Пример #8
0
            public void draw(Canvas canvas)
            {
                int     width  = mBounds.Width();
                int     height = mBounds.Height();
                int     cx     = width / 2;
                int     cy     = height / 2;
                Boolean drawTriggerWhileFinishing = false;
                int     restoreCount = canvas.Save();

                canvas.ClipRect(mBounds);

                if (mRunning || (mFinishTime > 0))
                {
                    long  now         = AnimationUtils.CurrentAnimationTimeMillis();
                    long  elapsed     = (now - mStartTime) % ANIMATION_DURATION_MS;
                    long  iterations  = (now - mStartTime) / ANIMATION_DURATION_MS;
                    float rawProgress = (elapsed / (ANIMATION_DURATION_MS / 100f));

                    // If we're not running anymore, that means we're running through
                    // the finish animation.
                    if (!mRunning)
                    {
                        // If the finish animation is done, don't draw anything, and
                        // don't repost.
                        if ((now - mFinishTime) >= FINISH_ANIMATION_DURATION_MS)
                        {
                            mFinishTime = 0;
                            return;
                        }

                        // Otherwise, use a 0 opacity alpha layer to clear the animation
                        // from the inside out. This layer will prevent the circles from
                        // drawing within its bounds.
                        long  finishElapsed  = (now - mFinishTime) % FINISH_ANIMATION_DURATION_MS;
                        float finishProgress = (finishElapsed / (FINISH_ANIMATION_DURATION_MS / 100f));
                        float pct            = (finishProgress / 100f);
                        // Radius of the circle is half of the screen.
                        float clearRadius = width / 2;                        //* INTERPOLATOR.getInterpolation(pct);
                        mClipRect.Set(cx - clearRadius, 0, cx + clearRadius, height);
                        canvas.SaveLayerAlpha(mClipRect, 0, 0);
                        // Only draw the trigger if there is a space in the center of
                        // this refreshing view that needs to be filled in by the
                        // trigger. If the progress view is just still animating, let it
                        // continue animating.
                        drawTriggerWhileFinishing = true;
                    }

                    // First fill in with the last color that would have finished drawing.
                    if (iterations == 0)
                    {
                        canvas.DrawColor(Android.Graphics.Color.Blue);
                    }
                    else
                    {
                        if (rawProgress >= 0 && rawProgress < 25)
                        {
                            canvas.DrawColor(Android.Graphics.Color.AliceBlue);
                        }
                        else if (rawProgress >= 25 && rawProgress < 50)
                        {
                            canvas.DrawColor(Android.Graphics.Color.Blue);
                        }
                        else if (rawProgress >= 50 && rawProgress < 75)
                        {
                            canvas.DrawColor(Android.Graphics.Color.BlueViolet);
                        }
                        else
                        {
                            canvas.DrawColor(Android.Graphics.Color.CadetBlue);
                        }
                    }

                    // Then draw up to 4 overlapping concentric circles of varying radii, based on how far
                    // along we are in the cycle.
                    // progress 0-50 draw mColor2
                    // progress 25-75 draw mColor3
                    // progress 50-100 draw mColor4
                    // progress 75 (wrap to 25) draw mColor1
                    if ((rawProgress >= 0 && rawProgress <= 25))
                    {
                        float pct = (((rawProgress + 25) * 2) / 100f);
                        drawCircle(canvas, cx, cy, mColor1, pct);
                    }
                    if (rawProgress >= 0 && rawProgress <= 50)
                    {
                        float pct = ((rawProgress * 2) / 100f);
                        drawCircle(canvas, cx, cy, mColor2, pct);
                    }
                    if (rawProgress >= 25 && rawProgress <= 75)
                    {
                        float pct = (((rawProgress - 25) * 2) / 100f);
                        drawCircle(canvas, cx, cy, mColor3, pct);
                    }
                    if (rawProgress >= 50 && rawProgress <= 100)
                    {
                        float pct = (((rawProgress - 50) * 2) / 100f);
                        drawCircle(canvas, cx, cy, mColor4, pct);
                    }
                    if ((rawProgress >= 75 && rawProgress <= 100))
                    {
                        float pct = (((rawProgress - 75) * 2) / 100f);
                        drawCircle(canvas, cx, cy, mColor1, pct);
                    }
                    if (mTriggerPercentage > 0 && drawTriggerWhileFinishing)
                    {
                        // There is some portion of trigger to draw. Restore the canvas,
                        // then draw the trigger. Otherwise, the trigger does not appear
                        // until after the bar has finished animating and appears to
                        // just jump in at a larger width than expected.
                        canvas.RestoreToCount(restoreCount);
                        restoreCount = canvas.Save();
                        canvas.ClipRect(mBounds);
                        drawTrigger(canvas, cx, cy);
                    }
                    // Keep running until we finish out the last cycle.
                    ViewCompat.PostInvalidateOnAnimation(mParent);
                }
                else
                {
                    // Otherwise if we're in the middle of a trigger, draw that.
                    if (mTriggerPercentage > 0 && mTriggerPercentage <= 1.0)
                    {
                        drawTrigger(canvas, cx, cy);
                    }
                }
                canvas.RestoreToCount(restoreCount);
            }