2013-02-18 89 views
4

我有这个签名视图,使您可以基本上在手机屏幕上绘制。现在,我需要将此视图添加为背景,或者将它用作xml布局上的小部件,但我不知道如何执行此操作。所以请任何人都可以帮助我做到这一点。 这是我的签名视图类:将自定义视图添加到xml布局

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.RectF; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 

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

和我的主类:

public class Draw extends Activity { 
    DrawView drawView; 
    SignatureView signature; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     // Set full screen view 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
       WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 

     signature = new SignatureView(this, null,R.drawable.back); 

     setContentView(signature); 
     signature.requestFocus(); 
    } 

    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.my_options_menu, menu); 
     return true; 
    } 

    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case R.id.clear: 
      signature.clear(); 
      return true; 

     case R.id.red: 
      signature.setColor(Color.RED); 
      return true; 

     case R.id.blue: 
      signature.setColor(Color.BLUE); 
      return true; 
     case R.id.yellow: 
      signature.setColor(Color.YELLOW); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
     } 
    } 

    @Override 
    public void onBackPressed() { 
     this.finish(); 
     super.onBackPressed(); 
    } 
} 

回答

3

你会在你的XML布局由全名引用此,如com.example.myapp.SignatureView

<com.example.myapp.SignatureView android:id="@+id\my_id" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
</com.example.myapp.SignatureView> 

您可以在代码中引用这背后通常还

SignatureView sv = (SignatureView)findViewById(R.id.my_id); 
sv.setColor(Color.RED); 
1

将其添加到了XML,你添加一个标签这样<com.example.SignatureView />其中com。示例的东西是你的包替代名称。您可以像平常一样添加参数和子标签。

相关问题