2013-02-19 3 views
0

내 레이아웃에서 그리기 위해 맞춤 위젯과 같은 방식으로 사용할보기를 만들었습니다. 하지만 처음에는이 오류가 있습니다. 그러니 도와주세요!맞춤 위젯 통합

이이 내 SignatureView 클래스 내 주요 레이아웃

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 
    <com.example.SignatureView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 
</LinearLayout> 

입니다 :

public class SignatureView extends View { 

     private static final float STROKE_WIDTH = 5f; 

     /** Need to track this so the dirty region can accommodate the stroke. **/ 
     private static final float HALF_STROKE_WIDTH = STROKE_WIDTH/2; 

     private Paint paint = new Paint(); 
     private Path path = new Path(); 

     /** 
     * Optimizes painting by invalidating the smallest possible area. 
     */ 
     private float lastTouchX; 
     private float lastTouchY; 
     private final RectF dirtyRect = new RectF(); 

     public SignatureView(Context context, AttributeSet attrs, int background) { 
     super(context, attrs); 
     setBackgroundResource(background); 
     paint.setAntiAlias(true); 
     paint.setColor(Color.BLACK); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeJoin(Paint.Join.ROUND); 
     paint.setStrokeWidth(STROKE_WIDTH); 

     } 

     public void setColor(int color){ 
      paint.setColor(color); 
     } 

     /** 
     * Erases the signature. 
     */ 
     public void clear() { 
     path.reset(); 

     // Repaints the entire view. 
     invalidate(); 
     } 

     @Override 
     protected void onDraw(Canvas canvas) { 
     canvas.drawPath(path, paint); 
     } 

     @Override 
     public boolean onTouchEvent(MotionEvent event) { 
     float eventX = event.getX(); 
     float eventY = event.getY(); 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
      path.moveTo(eventX, eventY); 
      lastTouchX = eventX; 
      lastTouchY = eventY; 
      // There is no end point yet, so don't waste cycles invalidating. 
      return true; 

      case MotionEvent.ACTION_MOVE: 
      case MotionEvent.ACTION_UP: 
      // Start tracking the dirty region. 
      resetDirtyRect(eventX, eventY); 

      // When the hardware tracks events faster than they are delivered, the 
      // event will contain a history of those skipped points. 
      int historySize = event.getHistorySize(); 
      for (int i = 0; i < historySize; i++) { 
       float historicalX = event.getHistoricalX(i); 
       float historicalY = event.getHistoricalY(i); 
       expandDirtyRect(historicalX, historicalY); 
       path.lineTo(historicalX, historicalY); 
      } 

      // After replaying history, connect the line to the touch point. 
      path.lineTo(eventX, eventY); 
      break; 

      default: 
//   Log.("Ignored touch event: " + event.toString()); 
      return false; 
     } 

     // Include half the stroke width to avoid clipping. 
     invalidate(
      (int) (dirtyRect.left - HALF_STROKE_WIDTH), 
      (int) (dirtyRect.top - HALF_STROKE_WIDTH), 
      (int) (dirtyRect.right + HALF_STROKE_WIDTH), 
      (int) (dirtyRect.bottom + HALF_STROKE_WIDTH)); 

     lastTouchX = eventX; 
     lastTouchY = eventY; 

     return true; 
     } 

     /** 
     * Called when replaying history to ensure the dirty region includes all 
     * points. 
     */ 
     private void expandDirtyRect(float historicalX, float historicalY) { 
     if (historicalX < dirtyRect.left) { 
      dirtyRect.left = historicalX; 
     } else if (historicalX > dirtyRect.right) { 
      dirtyRect.right = historicalX; 
     } 
     if (historicalY < dirtyRect.top) { 
      dirtyRect.top = historicalY; 
     } else if (historicalY > dirtyRect.bottom) { 
      dirtyRect.bottom = historicalY; 
     } 
     } 

     /** 
     * Resets the dirty region when the motion event occurs. 
     */ 
     private void resetDirtyRect(float eventX, float eventY) { 

     // The lastTouchX and lastTouchY were set when the ACTION_DOWN 
     // motion event occurred. 
     dirtyRect.left = Math.min(lastTouchX, eventX); 
     dirtyRect.right = Math.max(lastTouchX, eventX); 
     dirtyRect.top = Math.min(lastTouchY, eventY); 
     dirtyRect.bottom = Math.max(lastTouchY, eventY); 
     } 
    } 

이 내가 내 주요 그리기 클래스에있는 것입니다 :

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     } 

그리고 마지막으로 이게 내가 logCat에 넣는거야.

02-19 17:41:51.708: E/AndroidRuntime(7530): FATAL EXCEPTION: main 
02-19 17:41:51.708: E/AndroidRuntime(7530): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.Draw}: android.view.InflateException: Binary XML file line #6: Error inflating class com.example.SignatureView 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1662) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1678) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.app.ActivityThread.access$1500(ActivityThread.java:118) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:932) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.os.Handler.dispatchMessage(Handler.java:99) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.os.Looper.loop(Looper.java:130) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.app.ActivityThread.main(ActivityThread.java:3698) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at java.lang.reflect.Method.invoke(Method.java:507) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at dalvik.system.NativeStart.main(Native Method) 
02-19 17:41:51.708: E/AndroidRuntime(7530): Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class com.example.SignatureView 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.view.LayoutInflater.createView(LayoutInflater.java:508) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:570) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:623) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.view.LayoutInflater.inflate(LayoutInflater.java:408) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.app.Activity.setContentView(Activity.java:1657) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at com.example.Draw.onCreate(Draw.java:13) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1626) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  ... 11 more 
02-19 17:41:51.708: E/AndroidRuntime(7530): Caused by: java.lang.NoSuchMethodException: SignatureView(Context,AttributeSet) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at java.lang.Class.getMatchingConstructor(Class.java:643) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at java.lang.Class.getConstructor(Class.java:472) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  at android.view.LayoutInflater.createView(LayoutInflater.java:480) 
02-19 17:41:51.708: E/AndroidRuntime(7530):  ... 21 more 

답변

4

오류가 꽤 자기 explainatory입니다. 이런 식으로, 당신의 SignatureView 클래스에 그 생성자를 추가 : 생성자 누락처럼

public SignatureView(Context c, AttributeSet as){ 
    super(c, as); 
} 
+0

그걸 보지 못했습니다. –

+0

이제는 작동하지만,이 모든 것을 시도 할 때마다 \t signature = (SignatureView) findViewById (R.id.signature); \t \t signature.setColor (Color.MAGENTA); \t \t setContentView (R.layout.main); com.android.internal.os.ZygoteInit.main (ZygoteInit.java:633) \t에서 02-19 18 : 24 : 42.837 : E/AndroidRuntime (12336) : \t at dalvik.system.NativeStart. main (네이티브 메서드) 02-19 18 : 24 : 42.837 : E/AndroidRuntime (12336) : 원인 : java.lang.NullPointerException E/AndroidRuntime (12336) : \t at com.example.Draw.onCreate (그리기. java : 19) –

+0

새로운 질문을 올리십시오. 모든 relavent 코드와 전체 스택 추적을 포함하십시오. 주석을 읽는 코드/로그는 거의 불가능합니다. – FoamyGuy

1

컨텍스트 및 AttributeSet을 사용하는 생성자가 필요합니다. 세 번째 매개 변수를 추가했습니다. XML을 통해 팽창 할 때 작동하지 않습니다. 정확한 서명이 작동해야합니다.

또한 기본 스타일을 적용하면 xml 인플레이터가 실수로 현재 3 매개 변수 메서드를 호출하는 3 매개 변수 버전 (세 번째는 테마의 리소스 ID 임)을 찾습니다. 최종 결과는 무작위 테마 ID의 backgroudn 리소스를 설정하려고하는 것이고, 결과는 어떻게 될지 모르겠지만 추측은 충돌입니다.

Caused by: java.lang.NoSuchMethodException: SignatureView(Context,AttributeSet) 

당신은 단지 문맥을 취하는 생성자를 가지고 있지 않으며, 속성 세트 :

1
02-19 17:41:51.708: E/AndroidRuntime(7530): Caused by: java.lang.NoSuchMethodException: ***SignatureView(Context,AttributeSet)*** 

가 같은데? SignatureView (Context, AttributeSet)에 대한 생성자를 추가하고 이것이 어떻게 작동하는지보십시오.

대신 생성자에서 int background을 전달하려면 xml 속성으로 전달하십시오. 그렇게하면 기본 생성자에 대한 답장을 계속할 수 있으며 xml에서 배경을 설정할 수있는 유연성을 제공합니다.