修改后的多点触控“手指画”会在手指以错误的顺序向上时绘制多余的线条



我修改了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 

它从第一根手指离开屏幕的点到第二根手指在妈妈处的点画一条线。如果我以同样的方式使用三根或四根手指,也会发生同样的情况。我该如何解决这个问题?这是我的代码。(此代码依赖的所有类都在 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);
    }
}

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

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

最新更新