android - ScrollView 事件覆盖 DrawView 事件

标签 android events scroll touch-event overwrite

我在 ScrollView 上有一个绘制 View 。现在,当您不滚动并书写时,就没有问题了。一切看起来都很好。 但是,滚动后,您可以垂直绘制,但是一旦绘制,它就会将您的 Y 坐标设置为 ScrollView 的 Y 坐标(我认为)

我怀疑scrollevent正在覆盖onTouch事件。但我还不知道如何解决它。

例如

07-11 13:17:46.903  25508-25508/ V/﹕ Y - 8859.633
07-11 13:17:46.913  25508-25508/ V/﹕ Y - 8856.579
07-11 13:17:46.913  25508-25508/ V/﹕ Y - 8856.579
07-11 13:17:46.933  25508-25508/ V/﹕ Y - 8851.542
07-11 13:17:46.933  25508-25508/ V/﹕ Y - 8851.542
07-11 13:17:46.953  25508-25508/ V/﹕ Y - 8847.878
07-11 13:17:46.973  25508-25508/ V/﹕ Y - 544.6034 (as soon as I paint vertically up or down)

下面的图片说明了发生的情况。黄色荧光笔是我的笔/手指,蓝色是实际的绘图。

未向下滚动时

enter image description here

向下滚动时以及向上或向下绘制时

enter image description here

代码

public class MainActivity extends Activity {
    DrawingView dv ;
    private Paint mPaint;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

       dv = new DrawingView(this);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.GREEN);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(12);

        ScrollView mScrollView = new ScrollView(this);
        mScrollView.addView(dv);
        setContentView(mScrollView);

        mScrollView.setOnTouchListener( new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent m)
            {
                if(m.getTouchMajor() == 0.0f) {
                    Log.v("xxxx","Scroll Touch Pen");
                    dv.onTouchEvent(m);  <-- I know I am not passing the correct MotionEvent, but I have NO idea how to get the right one. At least this way I'm a "bit" closer to solving it as I can write horizontally as well without scrolling.
                    return true;
                }
                else
                {
                    Log.v("xxxx","Scroll Touch Fingure");

                    return false;
                }
            }


        });
    }

还有我的DrawingView

 public class DrawingView extends View {

        public int width;
        public  int height;
        private Bitmap  mBitmap;
        private Canvas  mCanvas;
        private Path    mPath;
        private Paint   mBitmapPaint;
        Context context;
        private Paint circlePaint;
        private Path circlePath;
        Rect clipBounds_canvas;

        public DrawingView(Context c) {
            super(c);
            context=c;
            mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);
            circlePaint = new Paint();
            circlePath = new Path();
            circlePaint.setAntiAlias(true);
            circlePaint.setColor(Color.BLUE);
            circlePaint.setStyle(Paint.Style.STROKE);
            circlePaint.setStrokeJoin(Paint.Join.MITER);
            circlePaint.setStrokeWidth(4f);
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);

            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mBitmap);

        }
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            clipBounds_canvas = canvas.getClipBounds();
            canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);

            canvas.drawPath( mPath,  mPaint);

            canvas.drawPath( circlePath,  circlePaint);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // Compute the height required to render the view
            // Assume Width will always be MATCH_PARENT.
            int width = MeasureSpec.getSize(widthMeasureSpec);

            int height = 10000; 
            setMeasuredDimension(width, height);
        }
        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;


        private void touch_start(float x, float y) {
        //    mPath.reset();

            mPath.moveTo(x, y);
            mX = x;
            mY = y;
            Log.v("xxxx","Y - Start - " + y);

        }
        private void touch_move(float x, float y) {
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);
            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
                mX = x;
                mY = y;

                Log.v("xxxx","Y - Move - " + y);

                circlePath.reset();
                circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
            }
        }
        private void touch_up() {
            mPath.lineTo(mX, mY);
            circlePath.reset();
            // commit the path to our offscreen
            mCanvas.drawPath(mPath,  mPaint);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();

            Log.v("xxxx","Y - " + y);

            if(event.getTouchMajor() == 0.0f) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        touch_start(x, y);
                        invalidate();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        touch_move(x, y);
                        invalidate();
                        break;
                    case MotionEvent.ACTION_UP:
                        touch_up();
                        invalidate();
                        break;
                }
                return true;

//                handleTouch(event);
//                return true;
            }
            else
            {
                return false;
            }
        }
    }

您是否能够看到我如何防止 ScrollView 覆盖我的运动事件(或者如果可能的话,至少有两个单独的事件。

最佳答案

找到了一个很好的解决方案here, that worked perfectly

就用这个方法

public static void disableTouchTheft(View view) {
    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            view.getParent().requestDisallowInterceptTouchEvent(true);
            switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_UP:
                view.getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }
            return false;
        }
    });
}

关于android - ScrollView 事件覆盖 DrawView 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24699575/

相关文章:

java - 从android发送序列化数据到java

android - 谷歌地图安卓 : How can i draw a route line to see directions

javascript - 我的元素上的哪个 jQuery 附加事件首先触发?

WPF:列表框,将所选项目居中

android - SMS检索器api android在vivo v15 pro,redmi note 4中不起作用

android - 在不访问外部存储的情况下使用 osmdroid

jquery - 如何在 jQuery 中撤消 event.stopPropagation?

node.js - 如何为Node中的对象实例添加事件能力?

reactjs - 滚动 React 时更改样式

javascript - 使用 jQuery 更改依赖于滚动位置的类时遇到问题