2012-03-22 5 views
0

안드로이드 개발에 익숙합니다. 손가락을 따라 선을 그리는 앱을 개발하려고합니다. m 개발자 가이드의 예제 TouchPaint의 도움을받습니다. m는 사람을 어떻게 해야할지 코드안드로이드 - 터치시 터치시 오류 발생시

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)); 
       } 
      } 

getPaintModeForTool(event.getToolType(j), mode)도 여기에

event.getHistoricalAxisValue(MotionEvent.AXIS_DISTANCE, j, i)에 .. 이벤트에 오류가 있습니다 받고?

+0

어떤 종류의 오류가 있습니까? logcat을 게시하십시오. – Egor

답변

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 mate! .. 일했다! –

+0

좋아요, 원하는 경우 답변으로 설정하십시오. – sciutand

+0

좋은 코드입니다. 한 가지 문제, clear() 메서드가 작동하지 않습니다. / – Pete

관련 문제