android - modifiied多点触控如果手指按错误顺序上升,FingerPaint会画出多余的线条

时间:2014-01-11 11:58:06

标签: android paint multi-touch

我从Android API修改了FingerPaint演示以支持多点触控。它的工作正常,但形成以下问题。在这种情况下:

  Touch order: First Finger--Second Finger__________Lift order: Second Finger---First Finger

一切都很好。但是......在这种情况下:

  Touch order: First Finger--Second Finger__________Lift order: First Finger---SecondFinger 
它从First Finger离开屏幕到第二个手指在妈妈的位置画了一条线。如果我以同样的方式使用三个或四个手指就会发生这种情况。我怎么能解决这个问题?这是我的代码。 (此代码所依赖的所有类都位于Android API的示例文件夹中)

public class FingerPaint extends GraphicsActivity {
 int startx0,startx1,starty0,starty1,startx2,starty2,startx3,starty3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(0xFFFF0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(12);

        mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
                                       0.4f, 6, 3.5f);

        mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
    }

    private Paint       mPaint;
    private MaskFilter  mEmboss;
    private MaskFilter  mBlur;

    public void colorChanged(int color) {
        mPaint.setColor(color);
    }

    public class MyView extends View {



        private Bitmap  mBitmap;
        private Canvas  mCanvas;
        private Path    mPath;
        private Paint   mBitmapPaint;

        public MyView(Context c) {
            super(c);

            mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        }

        @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) {
            canvas.drawColor(0xFFAAAAAA);

            canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

            canvas.drawPath(mPath, mPaint);
        }




        @Override
        public boolean onTouchEvent(MotionEvent event) {


            switch (event.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                     startx0 = (int) event.getX(0);
                     starty0 = (int) event.getY(0);
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    try{
                        startx1 = (int) event.getX(1);
                        starty1 = (int) event.getY(1);

                    }catch(Exception e){}

                    try{
                        startx2 = (int) event.getX(2);
                        starty2 = (int) event.getY(2);
                    }catch(Exception e){}
                    try{
                        startx3 = (int) event.getX(3);
                        starty3 = (int) event.getY(3);
                    }catch(Exception e){}

                    break;
                case MotionEvent.ACTION_MOVE:
                    try{
                        int x0 = (int) event.getX(0);
                        int y0 = (int) event.getY(0);
                        mCanvas.drawLine(startx0, starty0, x0, y0, mPaint);
                        startx0=x0;
                        starty0=y0;
                        invalidate();
                    }catch(Exception e){}
                    try{
                        int x1 = (int) event.getX(1);
                        int y1 = (int) event.getY(1);

                        mCanvas.drawLine(startx1, starty1, x1, y1, mPaint);
                        startx1=x1;
                        starty1=y1;
                        invalidate();
                    }catch(Exception e){}
                    try{
                        int x2 = (int) event.getX(2);
                        int y2 = (int) event.getY(2);
                        mCanvas.drawLine(startx2, starty2, x2, y2, mPaint);
                        startx2=x2;
                        starty2=y2;
                        invalidate();
                    }catch(Exception e){}
                    try{

                        int x3 = (int) event.getX(3);
                        int y3 = (int) event.getY(3);
                        mCanvas.drawLine(startx3, starty3, x3, y3, mPaint);
                        startx3=x3;
                        starty3=y3;
                        invalidate();
                    }catch(Exception e){}
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    break;
                case MotionEvent.ACTION_UP:

                    break;
            }
            return true;
        }
    }

    private static final int COLOR_MENU_ID = Menu.FIRST;
    private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
    private static final int BLUR_MENU_ID = Menu.FIRST + 2;
    private static final int ERASE_MENU_ID = Menu.FIRST + 3;
    private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
        menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
        menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
        menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
        menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z');

        /****   Is this the mechanism to extend with filter effects?
        Intent intent = new Intent(null, getIntent().getData());
        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
        menu.addIntentOptions(
                              Menu.ALTERNATIVE, 0,
                              new ComponentName(this, NotesList.class),
                              null, intent, 0, null);
        *****/
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        mPaint.setXfermode(null);
        mPaint.setAlpha(0xFF);

        switch (item.getItemId()) {
            case EMBOSS_MENU_ID:
                if (mPaint.getMaskFilter() != mEmboss) {
                    mPaint.setMaskFilter(mEmboss);
                } else {
                    mPaint.setMaskFilter(null);
                }
                return true;
            case BLUR_MENU_ID:
                if (mPaint.getMaskFilter() != mBlur) {
                    mPaint.setMaskFilter(mBlur);
                } else {
                    mPaint.setMaskFilter(null);
                }
                return true;
            case ERASE_MENU_ID:
                mPaint.setXfermode(new PorterDuffXfermode(
                                                        PorterDuff.Mode.CLEAR));
                return true;
            case SRCATOP_MENU_ID:
                mPaint.setXfermode(new PorterDuffXfermode(
                                                    PorterDuff.Mode.SRC_ATOP));
                mPaint.setAlpha(0x80);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

1 个答案:

答案 0 :(得分:0)

一旦举起第二根手指,只有一根手指向下。 这意味着event.getX(0)将包含剩余手指的数据 - 如果您抬起第一根手指,第二根手指的数据将从getX(1)报告为getX(0)

您不应该依赖触摸数组中的位置来识别手指,您应该使用MotionEvent.getPointerId(int)找出哪个手指在哪个位置并使用它来将事件映射到线条。