2013-03-27 67 views
0

好吧,這是我的完整CanvasView,我沒有創建位圖,我真的不知道該怎麼做。如果你瞭解它,如果你能幫助我,請做。先謝謝你!保存功能在FirstActivity中,它表示位圖爲空。如何創建繪製位圖?

public class CanvasView extends View{ 

private static final float STROKE_WIDTH = 5f; 
private static final float HALF_STROKE_WIDTH = STROKE_WIDTH/2; 
Paint erasePaint = new Paint(); 
Paint paint = new Paint(); 
Path path = new Path(); 

float lastTouchX,lastTouchY; 

AlertDialog.Builder alert; 

RectF ovalRectangle = new RectF(); 
RectF dirtyRect = new RectF(); 

MyRectangle myRectangle; 
MyOval myOval; 
MyCircle myCircle; 
MyFreehand myFreehand; 
MyLine myLine; 
MyEraser myEraser; 

List<MyEraser> eraserList = new ArrayList<MyEraser>(); 
List<MyLine> lineList = new ArrayList<MyLine>(); 
List<MyFreehand> freehandList = new ArrayList<MyFreehand>(); 
List<MyCircle> circleList = new ArrayList<MyCircle>(); 
List<MyOval> ovalList = new ArrayList<MyOval>(); 
List<MyRectangle> rectangleList = new ArrayList<MyRectangle>(); 



public boolean dashedLine = false; 
public DashPathEffect dashEffect = new DashPathEffect(new float[]{20,30}, 0); 
private Paint mBitmapPaint; 
private Bitmap mBitmap; 

public String textValue; 

public CanvasView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    setBackgroundColor(Color.WHITE); 


    if (android.os.Build.VERSION.SDK_INT >= 11) 
    { 
     turnOffHardwareAcc(); 
    } 


    erasePaint.setColor(Color.WHITE); 
    //erasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 

    erasePaint.setAntiAlias(true); 
    erasePaint.setStyle(Paint.Style.STROKE); 
    erasePaint.setStrokeJoin(Paint.Join.ROUND); 
    erasePaint.setStrokeWidth(12); 

    paint.setColor(Color.BLACK); 
    paint.setStyle(Paint.Style.STROKE); 

    paint.setAntiAlias(true); 
    paint.setStrokeJoin(Paint.Join.ROUND); 
    paint.setStrokeWidth(STROKE_WIDTH); 
    paint.setTextSize(34); 

    setMode(7);//default = 7 - free hand; 

    mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888); 
    mBitmapPaint = new Paint(Paint.DITHER_FLAG); 

    /* input dialog*/ 

    //setInputDialog(); 

} 
EditText input; 
public void setInputDialog(){ 

    alert = new AlertDialog.Builder(getContext()); 
    alert.setTitle("Title"); 
    alert.setMessage("Write text"); 

    // Set an EditText view to get user input 
    input = new EditText(getContext()); 
    alert.setView(input); 

    alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int whichButton) { 
     textValue= input.getText().toString(); 
     Toast.makeText(getContext(), textValue, Toast.LENGTH_SHORT).show(); 
     // Do something with value! 
     } 
    }); 

    alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int whichButton) { 
     // Canceled. 
     } 
    }); 

    //alert.show(); 

} 

public void setDashLine(){ 

    dashedLine = true; 
    paint = new Paint(); 
    paint.setPathEffect(dashEffect); 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setAntiAlias(true); 
    paint.setStrokeJoin(Paint.Join.ROUND); 
    paint.setStrokeWidth(STROKE_WIDTH); 
} 

public void setNormalLine(){ 
    //paint.setColor(Color.BLACK); 
    dashedLine = false; 

    paint.setPathEffect(null); 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setPathEffect(null); 
    paint.setAntiAlias(true); 
    paint.setStrokeJoin(Paint.Join.ROUND); 
    paint.setStrokeWidth(STROKE_WIDTH); 
} 

@TargetApi(11) 
public void turnOffHardwareAcc() // to enable dashed lines 
{ 

    this.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
} 

//public void setPaint(int color,) 

@TargetApi(11) 
protected void onDraw(Canvas canvas) { 

    if(dashedLine){ 
     paint.setPathEffect(dashEffect); 
    } 
    else { 
     paint.setPathEffect(null); 
    } 

    if(bitmap!=null){ 

     canvas.drawBitmap(bitmap, 0, 0, paint); 
     for(MyCircle circle:circleList){// draw circles 

      myCanvas.drawCircle(getCircleMidPointX(circle.firstX, circle.lastX),getCircleMidPointY(circle.firstY, circle.lastY),circle.radius,myPaint); 
     } 

    } 


    for(MyLine line:lineList){ //draw lines 
     if(dashedLine) 
      line.paint.setPathEffect(dashEffect); 
     else 
      line.paint.setPathEffect(null); 
      canvas.drawLine(line.xStart, line.yStart, line.xEnd, line.yEnd, line.paint); 
     } 

    for(MyCircle circle:circleList){// draw circles 

     canvas.drawCircle(getCircleMidPointX(circle.firstX, circle.lastX),getCircleMidPointY(circle.firstY, circle.lastY),circle.radius,paint); 
    } 

    for(MyOval oval:ovalList){ 
     if(dashedLine) 
      oval.paint.setPathEffect(dashEffect); 
     else oval.paint.setPathEffect(null); 

      ovalRectangle.set(oval.getX1(),oval.getY1(),oval.getX2(),oval.getY2()); 
      canvas.drawOval(ovalRectangle, oval.paint); 
    } 

    for(MyRectangle rectangle:rectangleList){ 
     if(dashedLine) 
      rectangle.paint.setPathEffect(dashEffect); 
     else rectangle.paint.setPathEffect(null); 

      canvas.drawRect(rectangle.getX1(),rectangle.getY1(),rectangle.getX2(),rectangle.getY2(),rectangle.paint); 
    } 

    for(MyEraser e:eraserList){ 
      canvas.drawPath(e.p,erasePaint); 
      invalidate(); 
    } 
    if(textValue!= null) 
     canvas.drawText(textValue, xStart, yStart, paint); 
    canvas.drawPath(path, paint); 
    //path.reset(); 

} 

final OnTouchListener drawLineListener = new OnTouchListener() { 
    public boolean onTouch(View v, MotionEvent event) { 

     FirstActivity.ll.setVisibility(LinearLayout.GONE); 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       myLine = new MyLine(); 
       myLine.xStart = event.getX(); 
       myLine.yStart = event.getY(); 

      return true; 

      case MotionEvent.ACTION_MOVE: 
      case MotionEvent.ACTION_UP: 
      myLine.xEnd = event.getX(); 
      myLine.yEnd = event.getY(); 
      invalidate(); 
      lineList.add(myLine); 
      break; 

      default: 
      Log.d("mock it up", "Unknown touch event " + event.toString()); 
      return false; 
     } 
     return true; 

    } 
}; 

final OnTouchListener drawDashedLineListener = new OnTouchListener() { 
    public boolean onTouch(View v, MotionEvent event) { 

     FirstActivity.ll.setVisibility(LinearLayout.GONE); 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
      return true; 

      case MotionEvent.ACTION_MOVE: 
      case MotionEvent.ACTION_UP: 

      break; 

      default: 
      Log.d("mock it up", "Unknown touch event " + event.toString()); 
      return false; 
     } 
     return true; 

    } 
}; 

final OnTouchListener drawCircleListener = new OnTouchListener(){ 

    public boolean onTouch(View v, MotionEvent event) { 

     FirstActivity.ll.setVisibility(LinearLayout.GONE); 

     float eventX = event.getX(); 
     float eventY = event.getY(); 



     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
      // path.moveTo(eventX, eventY); 
       Toast.makeText(getContext(), "action down - circle",Toast.LENGTH_SHORT).show(); 
       myCircle = new MyCircle(); 
       myCircle.firstX = eventX; 
       myCircle.firstY = eventY; 

      // There is no end point yet, so don't waste cycles invalidating. 
      return true; 

      case MotionEvent.ACTION_MOVE: 

      case MotionEvent.ACTION_UP: 
      myCircle.lastX = eventX; 
      myCircle.lastY = eventY; 

      myCircle.radius = getRadius(myCircle.firstX,myCircle.firstY,myCircle.lastX,myCircle.lastY); 

      circleList.add(myCircle); 

      invalidate(); 
      break; 

      default: 
      Log.d("mock it up", "Unknown touch event " + event.toString()); 
      return false; 
     } 
    return true; 
    } 

}; 

final OnTouchListener drawOvalListener = new OnTouchListener() { 
     public boolean onTouch(View v, MotionEvent event) { 

      FirstActivity.ll.setVisibility(LinearLayout.GONE); 

      switch (event.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
       myOval = new MyOval(); 
       myOval.setX1(event.getX()); 
       myOval.setY1(event.getY()); 
       // There is no end point yet, so don't waste cycles invalidating. 
       return true; 

       case MotionEvent.ACTION_MOVE: 
       case MotionEvent.ACTION_UP: 

        myOval.setX2(event.getX()); 
        myOval.setY2(event.getY()); 

        invalidate(); 
        ovalList.add(myOval); 

       default: 
       Log.d("mock it up", "Unknown touch event " + event.toString()); 
       return false; 
      } 

     } 
    }; 

final OnTouchListener drawRectangleListener = new OnTouchListener() { 

     public boolean onTouch(View v, MotionEvent event) { 

      FirstActivity.ll.setVisibility(LinearLayout.GONE); 

      switch (event.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        myRectangle = new MyRectangle(); 
        myRectangle.setX1(event.getX()); 
        myRectangle.setY1(event.getY()); 
       return true; 

       case MotionEvent.ACTION_MOVE: 

       case MotionEvent.ACTION_UP: 

        myRectangle.setX2(event.getX()); 
        myRectangle.setY2(event.getY()); 
        invalidate(); 
        rectangleList.add(myRectangle); 

       break; 

       default: 
       Log.d("mock it up", "Unknown touch event " + event.toString()); 
       return false; 
      } 


      return true; 
     } 
}; 

final OnTouchListener eraseListener = new OnTouchListener() { 

    public boolean onTouch(View v, MotionEvent event) { 

    // erasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
     //FirstActivity.ll.setVisibility(LinearLayout.GONE); 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
      myEraser = new MyEraser(); 
       lastTouchX = event.getX(); 
       lastTouchY = event.getY(); 
       myEraser.mouseDown(event.getX(), event.getY()); 
       return true; 

      case MotionEvent.ACTION_MOVE: 
      case MotionEvent.ACTION_UP: 
       resetDirtyRect(event.getX(),event.getY()); 
       int historySize = event.getHistorySize(); 
       for(int i=0;i<historySize;i++){ 
        float historicalX = event.getHistoricalX(i); 
        float historicalY = event.getHistoricalY(i); 
        expandDirtyRect(historicalX, historicalY); 

        myEraser.mouseUp(historicalX, historicalY); 
      } 
       myEraser.mouseUp(event.getX(), event.getY()); 
       eraserList.add(myEraser); 
      break; 

      default: 
      Log.d("mock it up", "Unknown touch event " + event.toString()); 
      return false; 
     } 



     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 = event.getX(); 
      lastTouchY = event.getY(); 
     return true; 
    } 
}; 

final OnTouchListener drawFreeHandListener = new OnTouchListener() { 

    public boolean onTouch(View v, MotionEvent event) { 

     FirstActivity.ll.setVisibility(LinearLayout.GONE); 

     float eventX = event.getX(); 
     float eventY = event.getY(); 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
      // path.reset(); 
      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); 
      //path.reset(); 
      break; 

      default: 
      Log.d("mock it up", "Unknown 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; 
    } 
}; 

float xStart,yStart; 
final OnTouchListener textListener = new OnTouchListener() { 

    public boolean onTouch(View v, MotionEvent event) { 
     FirstActivity.ll.setVisibility(LinearLayout.GONE); 

    // Toast.makeText(getContext(), "add some text", Toast.LENGTH_SHORT).show(); 


     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       // 
       setInputDialog(); 
       xStart = event.getX(); 
       yStart = event.getY(); 
       alert.show(); 
      break; 

      case MotionEvent.ACTION_MOVE: 
      case MotionEvent.ACTION_UP: 
      // setInputDialog(); 
        break; 

      default: 
      Log.d("mock it up", "Unknown touch event " + event.toString()); 
      return false; 
     } 


     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 void setMode(int mode){ 
    switch(mode){ 
    case 1://draw line 
     Toast.makeText(getContext(), "draw line", Toast.LENGTH_SHORT).show(); 
     setOnTouchListener(drawLineListener); 
     break; 
    case 2://draw dashed line 
     Toast.makeText(getContext(), "dashed line", Toast.LENGTH_SHORT).show(); 
     break; 
    case 3:// draw circle 
     setOnTouchListener(drawCircleListener); 
     break; 
    case 4: //draw oval 
     setOnTouchListener(drawOvalListener); 
     break; 
    case 5: //draw rectangle 
     setOnTouchListener(drawRectangleListener); 
     break; 
    case 6: //erase 
     setOnTouchListener(eraseListener); 
     break; 
    case 7: //free-hand 
     setOnTouchListener(drawFreeHandListener); 
     break; 
    case 8: 
     setOnTouchListener(textListener); 
     break; 
    } 
} 

private Bitmap bitmap; 
private Canvas myCanvas; 
public Paint myPaint; 

public void setImage(Bitmap b){ 
    Toast.makeText(getContext(), "set Bitmap",Toast.LENGTH_SHORT).show(); 
    bitmap = b.copy(Bitmap.Config.ARGB_8888, true); 
    myCanvas = new Canvas(bitmap); 

    myPaint = new Paint(); 
    myPaint.setColor(Color.YELLOW); 
    myPaint.setAntiAlias(true); 
    myPaint.setStrokeWidth(8); 

    invalidate(); 
} 

public void changeColor(int color){ 
    paint = new Paint(paint); 
    paint.setColor(color); 
    //myPaint.setColor(color); 
} 

public float getRadius(float x1,float y1,float x2,float y2){ 
     float r = (float) (Math.sqrt((double)(Math.pow((y2-y1), 2.0)+Math.pow((x2-x1), 2.0)))/2); 
     return r; 
    } 

public float getCircleMidPointX(float x1,float x2){ 
     return (x1+x2)/2; 
    } 

public float getCircleMidPointY(float y1,float y2){ 
     return (y1+y2)/2; 
    } 

} 

回答

1

你必須創建位圖,就在那裏你要保存它的文件。然後,您必須根據位圖創建自己的Canvas,並將其傳遞給您的View的繪製方法。類似這樣的:

public boolean onOptionsItemSelected(MenuItem item){ 
    switch (item.getItemId()) { 
    case R.id.tools: 
    ll.setVisibility(LinearLayout.VISIBLE); 
    return true; 
    case R.id.import_pics: 
    getPhotos(); 
    return true; 
    case R.id.save: 
    { 
     Bitmap bitmap = Bitmap.createBitmap(theView.getWidth(),theView.getHeight,Config.ARGB_8888); 
     Canvas canvas = new Canvas(bitmap); 
     theView.draw(canvas); 
     storeImage(bitmap); 
     bitmap.recycle(); 
    } 
    return true; 
    case R.id.trash: 
    return true; 
    } 
    return false; 
} 

移動繪圖代碼繪製方法。

我想這就是你問的。這個問題並不是最清楚的問題。

+0

我發佈了所有的CanvasView,如果你能理解我的代碼。 – 2013-03-27 17:09:21