2013-08-19 101 views
4

我想創建一個小漆應用,在那裏我可以用一些顏色來繪製,我只測試了一個顏色變化到現在爲止它不能正常工作。當我點擊按鈕並開始使用新顏色繪製時,之前繪製的所有圖紙也會改變顏色。有人能幫我嗎?更改路徑顏色不改變以前的路徑

public class MyTouchEventView extends View { 

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



    public Button btnChange; 
    public LayoutParams params; 

    public MyTouchEventView(Context context) { 
     super(context); 

     paint.setAntiAlias(true); 
     paint.setColor(Color.BLACK); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeJoin(Paint.Join.ROUND); 
     paint.setStrokeWidth(1f); 


     btnChange = new Button(context); 
     btnChange.setText("Chaneg color"); 

     params = new LayoutParams(LayoutParams.WRAP_CONTENT, 
       LayoutParams.WRAP_CONTENT); 
     btnChange.setLayoutParams(params); 

     btnChange.setOnClickListener(new View.OnClickListener() { 

      public void onClick(View v) { 


       paint.setColor(Color.GREEN); 
      } 
     }); 


    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     canvas.drawPath(path, paint); 

    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     float pointX = event.getX(); 
     float pointY = event.getY(); 

     // Checks for the event that occurs 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      path.moveTo(pointX, pointY); 

      return true; 
     case MotionEvent.ACTION_MOVE: 
      path.lineTo(pointX, pointY); 

      break; 
     default: 
      return false; 
     } 


     postInvalidate(); 
     return true; 
    } 

} 
+0

http://stackoverflow.com/questions/17781069/android-null-exception-on-calling-function/17781110#17781110。檢查這個編輯部分是否有幫助 – Raghunandan

+0

謝謝你似乎是我在找什麼 – Katy

回答

4

這裏的問題是你只使用一個路徑。

您應該創建每個ACTION_DOWN了一條新路。對於這些路徑,您還必須存儲Paint。

例如,你可以定義兩個元素作爲成員的類:

public class Stroke { 
    private Path _path; 
    private Paint _paint; 
}// add constructor(Path, Paint) and accessors 

和中風在您的上下文列表:

List<Stroke> allStrokes = new ArrayList<Stroke>(); 

所以每ACTION_DOWN,您創建一個新的Stroke (所以一個新的路徑,和一個新的油漆與您選擇的顏色)。

而且在每個ACTION_MOVE上,您都檢索了最後一個添加的路徑,那麼您可以在lineTo的最後一點。

然後在你的onDraw,只是提請所有生成的筆跡:

for (Stroke s : allStrokes) { 
    canvas.drawPath(s.getPath(), s.getPaint()); 
} 

請注意,這個簡單的解決方案,你不能做一個多點觸控圖。爲此,您還必須存儲和處理MotionEvent ID。

編輯:下面是創建充滿隨機顏色筆觸工作的多點觸控漆例如:

DrawArea.java:

import android.content.Context; 
import android.graphics.*; 
import android.util.SparseArray; 
import android.view.MotionEvent; 
import android.view.View; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

public class DrawArea extends View { 

    private List<Stroke> _allStrokes; //all strokes that need to be drawn 
    private SparseArray<Stroke> _activeStrokes; //use to retrieve the currently drawn strokes 
    private Random _rdmColor = new Random(); 

    public DrawArea(Context context) { 
     super(context); 
     _allStrokes = new ArrayList<Stroke>(); 
     _activeStrokes = new SparseArray<Stroke>(); 
     setFocusable(true); 
     setFocusableInTouchMode(true); 
     setBackgroundColor(Color.WHITE); 
    } 

    public void onDraw(Canvas canvas) { 
     if (_allStrokes != null) { 
      for (Stroke stroke: _allStrokes) { 
       if (stroke != null) { 
        Path path = stroke.getPath(); 
        Paint painter = stroke.getPaint(); 
        if ((path != null) && (painter != null)) { 
         canvas.drawPath(path, painter); 
        } 
       } 
      } 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     final int action = event.getActionMasked(); 
     final int pointerCount = event.getPointerCount(); 

     switch (action) { 
      case MotionEvent.ACTION_DOWN: { 
       pointDown((int)event.getX(), (int)event.getY(), event.getPointerId(0)); 
       break; 
      } 
      case MotionEvent.ACTION_MOVE: { 
       for (int pc = 0; pc < pointerCount; pc++) { 
        pointMove((int) event.getX(pc), (int) event.getY(pc), event.getPointerId(pc)); 
       } 
       break; 
      } 
      case MotionEvent.ACTION_POINTER_DOWN: { 
       for (int pc = 0; pc < pointerCount; pc++) { 
        pointDown((int)event.getX(pc), (int)event.getY(pc), event.getPointerId(pc)); 
       } 
       break; 
      } 
      case MotionEvent.ACTION_UP: { 
       break; 
      } 
      case MotionEvent.ACTION_POINTER_UP: { 
       break; 
      } 
     } 
     invalidate(); 
     return true; 
    } 

    private void pointDown(int x, int y, int id) { 
     //create a paint with random color 
     Paint paint = new Paint(); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeWidth(10); 
     paint.setColor(_rdmColor.nextInt()); 

     //create the Stroke 
     Point pt = new Point(x, y); 
     Stroke stroke = new Stroke(paint); 
     stroke.addPoint(pt); 
     _activeStrokes.put(id, stroke); 
     _allStrokes.add(stroke); 
    } 

    private void pointMove(int x, int y, int id) { 
     //retrieve the stroke and add new point to its path 
     Stroke stroke = _activeStrokes.get(id); 
     if (stroke != null) { 
      Point pt = new Point(x, y); 
      stroke.addPoint(pt); 
     } 
    } 
} 

Stroke.java:

import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.Point; 

public class Stroke { 
    private Path _path; 
    private Paint _paint; 

    public Stroke (Paint paint) { 
     _paint = paint; 
    } 

    public Path getPath() { 
     return _path; 
    } 

    public Paint getPaint() { 
     return _paint; 
    } 

    public void addPoint(Point pt) { 
     if (_path == null) { 
      _path = new Path(); 
      _path.moveTo(pt.x, pt.y); 
     } else { 
      _path.lineTo(pt.x, pt.y); 
     } 
    } 
} 

MyActivity.java:

import android.app.Activity; 
import android.os.Bundle; 

public class MyActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     DrawArea da = new DrawArea(this); 
     setContentView(da); 
    } 
} 
+0

我將如何使用你的方法來解決我的問題? http://stackoverflow.com/questions/18521661/change-color-without-affecting-anything-previously-drawn – Si8

+0

我如何獲取在ACTION_MOVE最後添加的路徑? – Katy

+0

檢查我剛剛添加的示例 – leadrien

1

我的解決辦法:

public class PaintView extends ImageView { 
    private class Holder { 
     Path path; 
     Paint paint; 

     Holder(int color) { 
      path = new Path(); 

      paint = new Paint(); 
      paint.setAntiAlias(true); 
      paint.setStrokeWidth(4f); 
      paint.setColor(color); 
      paint.setStyle(Paint.Style.STROKE); 
      paint.setStrokeJoin(Paint.Join.ROUND); 
      paint.setStrokeCap(Paint.Cap.ROUND); 
     } 
    } 

    private int color = Color.WHITE; 
    private List<Holder> holderList = new ArrayList<Holder>(); 

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

    public PaintView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

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

    private void init() { 
     holderList.add(new Holder(color)); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     for (Holder holder : holderList) { 
      canvas.drawPath(holder.path, holder.paint); 
     } 
    } 

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

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       holderList.add(new Holder(color)); 
       holderList.get(holderList.size() - 1).path.moveTo(eventX, eventY); 
       return true; 
      case MotionEvent.ACTION_MOVE: 
       holderList.get(holderList.size() - 1).path.lineTo(eventX, eventY); 
       break; 
      case MotionEvent.ACTION_UP: 
       break; 
      default: 
       return false; 
     } 

     invalidate(); 
     return true; 
    } 

    public void resetPaths() { 
     for (Holder holder : holderList) { 
      holder.path.reset(); 
     } 
     invalidate(); 
    } 

    public void setBrushColor(int color) { 
     this.color = color; 
    } 
}