当手指在多点触控上移动时绘制圆圈

时间:2014-12-22 09:29:37

标签: android canvas geometry pinchzoom

我正在捏捏放大/缩小我的应用程序。我想捏时画圈子。我试过下面的代码。但有时它画了1个圆圈。有时它不是。我想根据我的手指动作绘制圆圈。我怎么能这样做?

public class MainActivity extends Activity implements OnTouchListener {
String TAG="activity";
View view;
Bitmap bitmap /*newBitmap*/;
Canvas canvas;
Paint paintLine,paintCircle;
String direction;
float startX = 0, startY = 0, endX = 0, endY = 0, upx = 0, upy = 0;

private float scale = 1f;
final float MINIMUM_THRESHOLD=10;
boolean isZoomed=false,isMultitouch=false;
private ScaleGestureDetector SGD;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    //this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.activity_main);
    view = (LinearLayout) findViewById(R.id.imageView1);
    view.setOnTouchListener(this);
    //detector=new GestureDetector(this);
    DisplayMetrics currentDisplay = view.getContext().getResources().getDisplayMetrics();
    float dw = currentDisplay.widthPixels;
    float dh = currentDisplay.heightPixels;

    SGD = new ScaleGestureDetector(this,new ScaleListener());

    bitmap = Bitmap.createBitmap((int) dw, (int) dh,
            Bitmap.Config.ARGB_8888);
    //bitmap= BitmapFactory.decodeResource(getResources(), R.drawable.fish);

    //newBitmap=bitmap.copy(Bitmap.Config.ARGB_8888, true);
    canvas = new Canvas(bitmap);
    paintLine = new Paint();


    paintLine.setStyle(Paint.Style.STROKE);
    paintLine.setStrokeCap(Paint.Cap.ROUND);
    paintLine.setStrokeWidth(10);
    paintLine.setColor(Color.GRAY);
    view.setBackground(new BitmapDrawable(null, bitmap));

    paintCircle=new Paint();
    paintCircle.setStyle(Paint.Style.STROKE);
    paintCircle.setStrokeWidth(5);
    paintCircle.setColor(Color.WHITE);
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub
        switch (event.getActionMasked()) {
        case MotionEvent.ACTION_POINTER_UP :
            //hideDrawing(true);
            SGD.onTouchEvent(event);
            Log.v(TAG, "test:multitouch pointer up");
            if(isZoomed){
                Toast.makeText(MainActivity.this, "zoom in", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(MainActivity.this, "zoom out", Toast.LENGTH_SHORT).show();
            }
            return true;
        case MotionEvent.ACTION_POINTER_DOWN:
            //hideDrawing(true);
            SGD.onTouchEvent(event);
            Log.v(TAG, "test:multitouch pointer down");
            return true;

        case MotionEvent.ACTION_DOWN:
            startX = event.getX();
            startY = event.getY();
            isMultitouch=false;
            Log.v(TAG, "test:starting cords("+startX+","+startY+")");
            break;
        case MotionEvent.ACTION_MOVE:
            upx = event.getX();
            upy = event.getY();
            if(event.getPointerCount()>1 || isMultitouch){
                //hideDrawing(true);
                float x1 = (event.getX(0) + event.getX(1)) / 2.0f;
                float y1 = (event.getY(0) + event.getY(1)) / 2.0f;
                double r = Math.sqrt(Math.pow(event.getX(1) - event.getX(0), 2.0f) + Math.pow(event.getY(1) - event.getY(0), 2.0f)) / 2.0f;
                canvas.drawCircle(x1, y1, (float) r, paintCircle);
                SGD.onTouchEvent(event);
                Log.v(TAG, "test:multitouch :move");
                return true;
            }else if(event.getPointerCount()==1 && !isMultitouch){
                Log.v(TAG, "test:singletouch : move");

                if(Math.abs(upx-startX)>MINIMUM_THRESHOLD||Math.abs(upy-startY)>MINIMUM_THRESHOLD){
                view.postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        if(Math.abs(upx-startX)<Math.abs(upy-startY))
                             canvas.drawLine(startX, startY,startX, upy, paintLine);
                        else
                             canvas.drawLine(startX, startY,upx, startY, paintLine);
                }
                  }, 300);
                view.invalidate();
                }
            }
            break;

        case MotionEvent.ACTION_UP:
            endX = event.getX();
            endY = event.getY();
            Log.v(TAG, "test:singletouch : up");
            Log.v(TAG, "test:actual ending cords("+endX+","+endY+")");
            if(!isMultitouch){
            if(Math.abs(endX-startX)>MINIMUM_THRESHOLD||Math.abs(endY-startY)>MINIMUM_THRESHOLD){
                if(Math.abs(endX-startX)<Math.abs(endY-startY))
                    endX=startX;
                else
                    endY=startY;
                Log.v(TAG, "test:edited ending cords("+endX+","+endY+")");
                view.invalidate();
                hideDrawing(false);
                calculateDistanceAndDirection();
                findDirection();
                }
            }
            break;
        }
    return true;

}

private void hideDrawing(boolean immediate) {
    if(immediate){
        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        view.invalidate();
    }else{
      view.postDelayed(new Runnable() {
        @Override
        public void run() {

            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            view.invalidate();
        }
      }, 500);
    }
}

private void calculateDistanceAndDirection() {
    double dist = Math.sqrt(Math.pow((startX - endX), 2)
            + Math.pow((startY - endY), 2));
    //Toast.makeText(this, "cords is: ("+startX +","+startY+")("+endX+","+endY+")", Toast.LENGTH_LONG).show();
    //  Toast.makeText(this, "distance :"+dist, Toast.LENGTH_SHORT).show(); 
}


    private void findDirection(){

         if (startY < endY) {

           direction="down";
           Toast.makeText(this, direction, Toast.LENGTH_SHORT).show();

         } else if (startY > endY){

             direction="up";
             Toast.makeText(this, direction, Toast.LENGTH_SHORT).show();
        }else if (startX > endX){

             direction="left";
             Toast.makeText(this, direction, Toast.LENGTH_SHORT).show();
       }else if (startX < endX){

           direction="right";
           Toast.makeText(this, direction, Toast.LENGTH_SHORT).show();
       }
     }

private class ScaleListener extends ScaleGestureDetector.
   SimpleOnScaleGestureListener {
   @Override
   public boolean onScale(ScaleGestureDetector detector) {
      scale *= detector.getScaleFactor();
      scale = Math.max(0.1f, Math.min(scale, 5.0f));
      isMultitouch=true;
     // matrix.setScale(scale, scale);
     // view.setImageMatrix(matrix);
      if( detector.getScaleFactor()<1.0f)
          isZoomed=false;
      else
          isZoomed=true;
     return true;
   }
}

}

1 个答案:

答案 0 :(得分:1)

参考http://developer.android.com/reference/android/view/MotionEvent.html MotionEvent支持您触摸屏幕的手指索引

  

getActionIndex()

     

对于ACTION_POINTER_DOWN或ACTION_POINTER_UP返回   getActionMasked(),这将返回关联的指针索引。