在使用GestureDetector实现Scroller后,如何更新Android ShapeDrawable边界更改?

时间:2014-10-15 07:15:13

标签: android android-canvas android-gesture android-shape

我尝试了什么:

我在onDraw(Canvas canvas)中绘制了指定边界的shapeDrawables。

添加Handle Input Gestures,允许视图在任何方向滚动,如此SO post.

中提到的2d滚动视图

问题:

当我滚动onScroll() GestureDetector shapeDrawable' 绑定更改时的视图!是否有任何方法可以在滚动时更改/更新已显示的shapeDrawable边界?

我已经实现了onTouchEvent(MotionEvent event),如果单击画布/视图上显示的Shape drawable,如果单击的x,y包含shapesrawable的边界,则删除drawable。当视图没有滚动时,这个东西工作正常,如果滚动视图绑定无法检测shaperawable因为绑定和x,y参数的变化。

代码:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.graphics.drawable.shapes.RectShape;
import android.graphics.drawable.shapes.Shape;
import android.os.Build;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;

import java.util.*;

public class ShapeDrawableView extends View {
    private List<ShapeDrawable> shapes = new ArrayList<ShapeDrawable>();
    private Integer[] mColors = { Color.BLACK, Color.BLUE, Color.GREEN,
            Color.RED };

    // If made programmatically and added with setContentView

    public ShapeDrawableView(Context context) {
        super(context);
    }

    private Scroller mScroller;
    private GestureDetector mDetector;

    public ShapeDrawableView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mDetector = new GestureDetector(ShapeDrawableView.this.getContext(),
                new GestureListener());
        if (Build.VERSION.SDK_INT < 11) {
            mScroller = new Scroller(getContext());
        } else {
            mScroller = new Scroller(getContext(), null, true);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (ShapeDrawable shape : shapes) {
            shape.draw(canvas);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        mDetector.onTouchEvent(event);
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX(); // Use getX(int) for multi-finger
                                        // gestures
            int y = (int) event.getY();
            if (!isDeletingExistingShape(x, y)) {
                shapes.add(makeShapeDrawable(x, y));
            }
            invalidate();
            return (true); // Handled touch event
        } else {
            return (false); // Did not handle touch event
        }
    }

    private boolean isDeletingExistingShape(int x, int y) {
        for (ShapeDrawable shape : shapes) {
            Rect bounds = shape.getBounds();
            if (bounds.contains(x, y)) {
                shapes.remove(shape);
                return (true);
            }
        }
        return (false);
    }

    private ShapeDrawable makeShapeDrawable(int x, int y) {
        int maxWidth = getWidth() / 10;
        int maxHeight = getHeight() / 10;
        Shape shape;
        if (Math.random() < 0.5) {
            shape = new OvalShape();
        } else {
            shape = new RectShape();
        }
        ShapeDrawable shapeD = new ShapeDrawable(shape);
        int width = RandomUtils.randomInt(maxWidth) + 5;
        int height = RandomUtils.randomInt(maxHeight) + 5;
        shapeD.setBounds(x - width / 2, y - height / 2, x + width / 2, y
                + height / 2);
        shapeD.getPaint().setColor(RandomUtils.randomElement(mColors));

        return (shapeD);
    }

    private class GestureListener extends
            GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                float distanceX, float distanceY) {
            // Set the pie rotation directly.
            // float scrollTheta = vectorToScalarScroll(
            // distanceX,
            // distanceY,
            // e2.getX() - mPieBounds.centerX(),
            // e2.getY() - mPieBounds.centerY());
            // setPieRotation(getPieRotation() - (int) scrollTheta /
            // FLING_VELOCITY_DOWNSCALE);

            scrollBy((int) distanceX, (int) distanceY);

            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            // Set up the Scroller for a fling
            /*
             * float scrollTheta = vectorToScalarScroll( velocityX, velocityY,
             * e2.getX() - mPieBounds.centerX(), e2.getY() -
             * mPieBounds.centerY()); mScroller.fling( 0, (int)
             * getPieRotation(), 0, (int) scrollTheta /
             * FLING_VELOCITY_DOWNSCALE, 0, 0, Integer.MIN_VALUE,
             * Integer.MAX_VALUE);
             * 
             * // Start the animator and tell it to animate for the expected
             * duration of the fling. if (Build.VERSION.SDK_INT >= 11) {
             * mScrollAnimator.setDuration(mScroller.getDuration());
             * mScrollAnimator.start(); }
             */

            mScroller.fling(getScrollX(), getScrollY(), -(int) velocityX,
                    -(int) velocityY, 0, (int) 100, 0, (int) 100);
            invalidate(); // don't remember if it's needed
            return true;

            // return true;
        }

        @Override
        public boolean onDown(MotionEvent e) {
            // The user is interacting with the pie, so we want to turn on
            // acceleration
            // so that the interaction is smooth.
            /*
             * mPieView.accelerate(); if (isAnimationRunning()) {
             * stopScrolling(); }
             */

            if (!mScroller.isFinished()) { // is flinging
                mScroller.forceFinished(true); // to stop flinging on touch
            }
            return true; // else won't work
            // return true;
        }
    }

}

Gist

1 个答案:

答案 0 :(得分:1)

只需在onTouchEvent中更新x和y:

x += getScrollX();
y += getScrollY();