2012-03-22 74 views
0

我是Android开发新手.. m试图开发一个应用程序来绘制一条线,以跟随手指.. m借助开发指南上的示例TouchPaint的帮助.. M于 事件得到一个错误.. getPaintModeForTool(event.getToolType(j), mode)event.getHistoricalAxisValue(MotionEvent.AXIS_DISTANCE, j, i)Android-绘制触摸线 - 事件上的错误

这里是代码

final int action = event.getActionMasked(); 

     if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE 
       /*|| action == MotionEvent.ACTION_HOVER_MOVE*/) { 
      final int N = event.getHistorySize(); 
      final int P = event.getPointerCount(); 
      for (int i = 0; i < N; i++) { 
       for (int j = 0; j < P; j++) { 
        paint(getPaintModeForTool(event.getToolType(j), mode), 
          event.getHistoricalX(j, i), 
          event.getHistoricalY(j, i), 
          event.getHistoricalPressure(j, i), 
          event.getHistoricalTouchMajor(j, i), 
          event.getHistoricalTouchMinor(j, i), 
          event.getHistoricalOrientation(j, i), 
          event.getHistoricalAxisValue(MotionEvent.AXIS_DISTANCE, j, i), 
          event.getHistoricalAxisValue(MotionEvent.AXIS_TILT, j, i)); 
       } 
      } 

做什么人?

+0

什么样的错误?请发布logcat。 – Egor 2012-03-22 08:28:00

回答

9

如果你正在寻找的只是一条线来跟随用户的触摸,这里是一个我用于签名捕获的类。它只是覆盖dispatchTouchEvent(MotionEvent事件),并从那里生成一个遵循用户手指的路径。它有一个非常好的功能,使曲线的路径;您会看到用户是否快速移动手指,新的和最后的偶数坐标相距甚远(包括与事件相关的任何历史值),并且最终出现锯齿状的路径。

import android.content.Context; 
import android.content.res.TypedArray; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.CompressFormat; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 

public class SignatureView extends View { 

    private final String LOG_TAG = this.getClass().getSimpleName(); 

    private float mSignatureWidth = 8f; 
    private int mSignatureColor = Color.BLACK; 
    private boolean mCapturing = true; 
    private Bitmap mSignature = null; 

    private static final boolean GESTURE_RENDERING_ANTIALIAS = true; 
    private static final boolean DITHER_FLAG = true; 

    private Paint mPaint = new Paint(); 
    private Path mPath = new Path(); 

    private final Rect mInvalidRect = new Rect(); 

    private float mX; 
    private float mY; 

    private float mCurveEndX; 
    private float mCurveEndY; 

    private int mInvalidateExtraBorder = 10; 

    public SignatureView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(); 
    } 

    public SignatureView(Context context) { 
     super(context); 
     init(); 
    } 

    public SignatureView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     init(); 
    } 

    private void init() { 
     setWillNotDraw(false); 

     mPaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS); 
     mPaint.setColor(mSignatureColor); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setStrokeWidth(mSignatureWidth); 
     mPaint.setDither(DITHER_FLAG); 
     mPath.reset(); 


    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     if (mSignature != null) { 
      canvas.drawBitmap(mSignature, null, new Rect(0, 0, getWidth(), 
        getHeight()), null); 
     } else { 
      canvas.drawPath(mPath, mPaint); 
     } 

    } 

    @Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
     if (mCapturing) { 
      processEvent(event); 
      Log.d(VIEW_LOG_TAG, "dispatchTouchEvent"); 
      return true; 
     } else { 
      return false; 
     } 
    } 

    private boolean processEvent(MotionEvent event) { 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      touchDown(event); 
      invalidate(); 
      return true; 
     case MotionEvent.ACTION_MOVE: 

      Rect rect = touchMove(event); 
      if (rect != null) { 
       invalidate(rect); 
      } 
      return true; 

     case MotionEvent.ACTION_UP: 

      touchUp(event, false); 
      invalidate(); 
      return true; 

     case MotionEvent.ACTION_CANCEL: 

      touchUp(event, true); 
      invalidate(); 
      return true; 

     } 

     return false; 

    } 

    private void touchUp(MotionEvent event, boolean b) { 
     // TODO Auto-generated method stub 

    } 

    private Rect touchMove(MotionEvent event) { 
     Rect areaToRefresh = null; 

     final float x = event.getX(); 
     final float y = event.getY(); 

     final float previousX = mX; 
     final float previousY = mY; 

     areaToRefresh = mInvalidRect; 

     // start with the curve end 
     final int border = mInvalidateExtraBorder; 
     areaToRefresh.set((int) mCurveEndX - border, (int) mCurveEndY - border, 
       (int) mCurveEndX + border, (int) mCurveEndY + border); 

     float cX = mCurveEndX = (x + previousX)/2; 
     float cY = mCurveEndY = (y + previousY)/2; 

     mPath.quadTo(previousX, previousY, cX, cY); 

     // union with the control point of the new curve 
     areaToRefresh.union((int) previousX - border, (int) previousY - border, 
       (int) previousX + border, (int) previousY + border); 

     // union with the end point of the new curve 
     areaToRefresh.union((int) cX - border, (int) cY - border, (int) cX 
       + border, (int) cY + border); 

     mX = x; 
     mY = y; 

     return areaToRefresh; 

    } 

    private void touchDown(MotionEvent event) { 
     float x = event.getX(); 
     float y = event.getY(); 

     mX = x; 
     mY = y; 
     mPath.moveTo(x, y); 

     final int border = mInvalidateExtraBorder; 
     mInvalidRect.set((int) x - border, (int) y - border, (int) x + border, 
       (int) y + border); 

     mCurveEndX = x; 
     mCurveEndY = y; 

    } 


    /** 
    * Erases the signature. 
    */ 
    public void clear() { 
     mSignature = null; 
     mPath.rewind(); 
     // Repaints the entire view. 
     invalidate(); 
    } 

    public boolean isCapturing() { 
     return mCapturing; 
    } 

    public void setIsCapturing(boolean mCapturing) { 
     this.mCapturing = mCapturing; 
    } 

    public void setSignatureBitmap(Bitmap signature) { 
     mSignature = signature; 
     invalidate(); 
    } 

    public Bitmap getSignatureBitmap() { 
     if (mSignature != null) { 
      return mSignature; 
     } else if (mPath.isEmpty()) { 
      return null; 
     } else { 
      Bitmap bmp = Bitmap.createBitmap(getWidth(), getHeight(), 
      Bitmap.Config.ARGB_8888); 
      Canvas c = new Canvas(bmp); 
      c.drawPath(mPath, mPaint); 
      return bmp; 
     } 
    } 

    public void setSignatureWidth(float width) { 
     mSignatureWidth = width; 
     mPaint.setStrokeWidth(mSignatureWidth); 
     invalidate(); 
    } 

    public float getSignatureWidth(){ 
     return mPaint.getStrokeWidth(); 
    } 

    public void setSignatureColor(int color) { 
     mSignatureColor = color; 
    } 

    /** 
    * @return the byte array representing the signature as a PNG file format 
    */ 
    public byte[] getSignaturePNG() { 
     return getSignatureBytes(CompressFormat.PNG, 0); 
    } 

    /** 
    * @param quality Hint to the compressor, 0-100. 0 meaning compress for small 
    *   size, 100 meaning compress for max quality. 
    * @return the byte array representing the signature as a JPEG file format 
    */ 
    public byte[] getSignatureJPEG(int quality) { 
     return getSignatureBytes(CompressFormat.JPEG, quality); 
    } 

    private byte[] getSignatureBytes(CompressFormat format, int quality) { 
     Log.d(LOG_TAG, "getSignatureBytes() path is empty: " + mPath.isEmpty()); 
     Bitmap bmp = getSignatureBitmap(); 
     if (bmp == null) { 
      return null; 
     } else { 
      ByteArrayOutputStream stream = new ByteArrayOutputStream(); 

      getSignatureBitmap().compress(format, quality, stream); 

      return stream.toByteArray(); 
     } 
    } 


} 
+3

thnx队友! .. 有效! – 2012-03-22 09:28:25

+0

太棒了,如果这是你想要的,请将其设置为答案。 – sciutand 2012-03-22 11:51:26

+0

伟大的代码。一个问题,clear()方法不适用于我:/ – Pete 2012-07-20 21:14:41