2017-05-14 98 views
2

我使用android.graphics.Path繪製了android.graphics.Canvas。我想允許用戶使用一系列顏色和筆觸寬度進行繪製,但是,每當顏色或筆觸寬度發生變化時,都會使用新顏色或筆觸寬度重新繪製。我怎樣才能解決這個問題?繪製多種顏色的路徑

XML:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_main" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    > 


    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal"> 
     <Button 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:id="@+id/btnW10" 
      android:layout_margin="3sp" 
      android:layout_weight="1" 
      android:text="Width10"/> 
     <Button 
      android:id="@+id/btnW40" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_margin="3sp" 
      android:layout_weight="1" 
      android:text="Width40"/> 
     <Button 
      android:id="@+id/btnW70" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_margin="3sp" 
      android:layout_weight="1" 

      android:text="Width70"/> 

    </LinearLayout> 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="20dp"></LinearLayout> 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal"> 
     <Button 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_margin="3sp" 
      android:layout_weight="1" 
      android:id="@+id/btnBlue" 
      android:text="Blue"/> 
     <Button 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_margin="3sp" 
      android:layout_weight="1" 
      android:id="@+id/btnRed" 
      android:text="Red"/> 
     <Button 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_margin="3sp" 
      android:layout_weight="1" 

      android:id="@+id/btnGreen" 
      android:text="Green"/> 

    </LinearLayout> 

    <com.vladislav.canvaswc.DrawLine 
     android:id="@+id/drwLine" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     /> 

</LinearLayout> 

main.java:

public class MainActivity extends AppCompatActivity implements View.OnClickListener 
{ 
    DrawLine dr; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Button btnB=(Button) findViewById(R.id.btnBlue); 
     Button btnG=(Button) findViewById(R.id.btnGreen); 
     Button btnR=(Button) findViewById(R.id.btnRed); 
     Button btnW10=(Button) findViewById(R.id.btnW10); 
     Button btnW40=(Button) findViewById(R.id.btnW40); 
     Button btnW70=(Button) findViewById(R.id.btnW70); 
     dr =(DrawLine) findViewById(R.id.drwLine); 
     btnB.setOnClickListener(this); 
     btnG.setOnClickListener(this); 
     btnR.setOnClickListener(this); 
     btnW10.setOnClickListener(this); 
     btnW40.setOnClickListener(this); 
     btnW70.setOnClickListener(this); 
    } 


    @Override 
    public void onClick(View v) { 
     switch(v.getId()) 
     { 
      case R.id.btnBlue : dr.changeColor(Color.BLUE);break; 
      case R.id.btnGreen : dr.changeColor(Color.GREEN);break; 
      case R.id.btnRed : dr.changeColor(Color.RED);break; 
      case R.id.btnW10 : dr.changeWidth(10f);break; 
      case R.id.btnW40 : dr.changeWidth(40f);break; 
      case R.id.btnW70 : dr.changeWidth(70f);break; 
     } 
    } 
} 

drawline.java ChangeWidthColor其我與2種方法changeColor() 和changeWidth()

public class DrawLine extends View implements ChangeWidthColor { 

    private Paint paint = new Paint(); 
    private Path path = new Path(); 
    public float x; 
    public float y; 

    public DrawLine(Context context) { 
     super(context); 
     init(context); 

    } 

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

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

    public void init(Context context) { 

     //paint.setColor(Color.BLACK); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeJoin(Paint.Join.MITER); 
     //paint.setStrokeWidth(5f); 

    } 

    @Override 
    public void changeColor(int color) { 
     paint.setColor(color); 


    } 

    @Override 
    public void changeWidth(float width) { 
     paint.setStrokeWidth(width); 

    } 


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

    } 


    @Override 
    public boolean onTouchEvent(MotionEvent event) { 


     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       x= event.getX(); 
       y= event.getY(); 
       path.moveTo(x, y); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       x= event.getX(); 
       y= event.getY(); 
       path.lineTo(x, y); 
       invalidate(); 
       break; 
      case MotionEvent.ACTION_UP: 
       invalidate(); 
       break; 
     } 
     invalidate(); 
     return true; 
    } 
} 
+0

整個路徑正在重繪與每次點擊的新型塗料。一種方法是維護一個Path和Paint對象列表,然後通過onDraw進行迭代。 – burntsugar

+0

@burntsugar 你可以一步一步告訴我我該怎麼做,我是新來的android –

回答

3

此解決方案維護路徑對象列表和整數列表用於存儲顏色。這些列表是並行的 - 每個列表中有1個條目用於路徑和顏色對。 onDraw迭代這些列表,使用相應的顏色繪製每個路徑。

每次用戶單擊以更改顏色時,都會創建一個新路徑。 ACTION_DOWN和ACTION_MOVE在路徑上調用moveTo(x,y)和lineTo(x,y),ACTION_UP則將Path和當前顏色添加到列表中。

注意:我還沒有實現中風寬度的解決方案,但是,您應該可以按照該示例自行添加它。

public class DrawLine extends View { 

    private Path path = new Path(); 
    private Paint paint = new Paint(); 
    private int currentColor = Color.BLACK; 
    private List<Path> paths = new ArrayList<Path>(); 
    private List<Integer> colors = new ArrayList<Integer>(); 
    private float x; 
    private float y; 

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

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

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

    public void init(Context context) { 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeJoin(Paint.Join.MITER); 
     paint.setColor(currentColor); 
    } 

    public void changeColor(int color) { 
     currentColor = color; 
     path = new Path(); 
    } 

    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     for (int x = 0; x < paths.size(); x++) { 
      paint.setColor(colors.get(x)); 
      canvas.drawPath(paths.get(x), paint); 
     } 
    } 

    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       x = event.getX(); 
       y = event.getY(); 
       path.moveTo(x, y); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       x = event.getX(); 
       y = event.getY(); 
       path.lineTo(x, y); 
       invalidate(); 
       break; 
      case MotionEvent.ACTION_UP: 
       paths.add(path); 
       colors.add(currentColor); 
       invalidate(); 
       break; 
     } 
     invalidate(); 
     return true; 
    } 
} 

`

-1

您接口無論何時您需要在您的自定義視圖中調用invalidate() ng與UI相關的內容。所以更新的方法將是:

@Override 
public void changeColor(int color) { 
    paint.setColor(color); 
    invalidate(); 

} 

@Override 
public void changeWidth(float width) { 
    paint.setStrokeWidth(width); 
    invalidate(); 
} 
+0

沒有工作你的解決方案。 –

+0

如果我畫線默認顏色是黑色,我點擊按鈕「藍色」,我的第一和第二行是藍色。但首先必須是黑色(默認)和第二藍色。爲什麼2行藍色? –

0
public class DrawLine extends View implements ChangeWidthColor { 


    private Path path = new Path(); 
    private Paint paint = new Paint(); 
    private int currentColor = Color.BLACK; 
    private float width = 1f; 
    public float x; 
    public float y; 

    private LinkedList<Integer> color = new LinkedList<Integer>(); 
    private LinkedList<Float> widthSize = new LinkedList<Float>(); 
    private LinkedList<Path> paths = new LinkedList<Path>(); 

    public DrawLine(Context context) { 
     super(context); 
     init(context); 


    } 

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

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

    public void init(Context context) { 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeJoin(Paint.Join.MITER); 
     paint.setColor(currentColor); 
     paint.setStrokeWidth(5f); 

    } 

    @Override 
    public void changeColor(int color) { 
     currentColor = color; 
     path = new Path(); 


    } 

    @Override 
    public void changeWidth(float width) { 
     this.width = width; 
     path = new Path(); 


    } 


    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     for (int i = 0; i < paths.size(); i++) { 
      paint.setStrokeWidth(widthSize.get(i)); 
      paint.setColor(color.get(i)); 
      canvas.drawPath(paths.get(i), paint); 
     } 


    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       x = event.getX(); 
       y = event.getY(); 
       path.moveTo(x, y); 
       break; 

      case MotionEvent.ACTION_MOVE: 
       x = event.getX(); 
       y = event.getY(); 
       path.lineTo(x, y); 
       invalidate(); 

       break; 
      case MotionEvent.ACTION_UP: 

       color.add(currentColor); 
       paths.add(path); 
       widthSize.add(width); 
       break; 
      default: 
       return false; 
     } 
     invalidate(); 
     return true; 
    } 


}