在画布中绘制不同颜色的线条

时间:2013-01-31 12:22:43

标签: java android android-canvas

这是我第一次使用Android中的Canvas类。

我想要的是在画布上绘制不同颜色的线条。我有一个我无法解决的问题。

我将第一行画成黑色,在我将颜色更改为红色并尝试以红色绘制第二行后,以黑色绘制的第一行变为红色。

我使用的代码是:

import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class DrawView extends View implements OnTouchListener 
{
    private Canvas      m_Canvas;

    private Path        m_Path;

    private Paint       m_Paint;

    ArrayList<Pair<Path, Paint>> paths = new ArrayList<Pair<Path, Paint>>();

    ArrayList<Pair<Path, Paint>> undonePaths = new ArrayList<Pair<Path, Paint>>(); 

    private float mX, mY;

    private static final float TOUCH_TOLERANCE = 4;

//  Bitmap canvasBackground;

    public DrawView(Context context) 
    {
        super(context);
        setFocusable(true);
        setFocusableInTouchMode(true);      
        this.setOnTouchListener(this);

        onCanvasInitialization();
    }      

    public void onCanvasInitialization()
    {
        m_Paint = new Paint();
        m_Paint.setAntiAlias(true);
        m_Paint.setDither(true);
        m_Paint.setColor(Color.parseColor("#37A1D1"));
        m_Paint.setStyle(Paint.Style.STROKE);
        m_Paint.setStrokeJoin(Paint.Join.ROUND);
        m_Paint.setStrokeCap(Paint.Cap.ROUND);
        m_Paint.setStrokeWidth(2);      

        m_Canvas = new Canvas();

        m_Path = new Path();
        Paint newPaint = new Paint(m_Paint);
        paths.add(new Pair<Path, Paint>(m_Path, newPaint));

//      Bitmap canvas = BitmapFactory.decodeResource(getResources(), R.drawable.theme1_img_note).copy(Bitmap.Config.ARGB_8888, true);
//      canvasBackground = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888 );
//      m_Canvas = new Canvas(canvasBackground);        
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) 
    {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {      
        for (Pair<Path, Paint> p : paths) 
        {
            canvas.drawPath(p.first, p.second);
        }
    }

    public boolean onTouch(View arg0, MotionEvent event) 
    {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) 
        {
            case MotionEvent.ACTION_DOWN:
            touch_start(x, y);
            invalidate();
            break;
            case MotionEvent.ACTION_MOVE:
            touch_move(x, y);
            invalidate();
            break;
            case MotionEvent.ACTION_UP:
            touch_up();
            invalidate();
            break;
        }
        return true;
    }

    private void touch_start(float x, float y) 
    {
        m_Path.reset();
        m_Path.moveTo(x, y);
        mX = x;
        mY = y;
    }

    private void touch_move(float x, float y) 
    {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) 
        {
            m_Path.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;
        }
    }
    private void touch_up() 
    {
        m_Path.lineTo(mX, mY);

        // commit the path to our offscreen
        m_Canvas.drawPath(m_Path, m_Paint);

        // kill this so we don't double draw            
        m_Path = new Path();
        Paint newPaint = new Paint(m_Paint); // Clones the mPaint object
        paths.add(new Pair<Path, Paint>(m_Path, newPaint));
    }

    public void onClickPenButton(int penWidth) 
    { 
        m_Paint.setStrokeWidth(penWidth);

        m_Path = new Path();
        Paint newPaint = new Paint(m_Paint); // Clones the mPaint object
        paths.add(new Pair<Path, Paint>(m_Path, newPaint));             
    }

    public void onClickPenColorButton(int penColor) 
    {       
        m_Paint.setColor(penColor);

        Paint newPaint = new Paint(m_Paint); // Clones the mPaint object
        paths.add(new Pair<Path, Paint>(m_Path, newPaint));
    }

    public void onClickUndo () 
    { 
        if (paths.size()>0) 
        { 
            undonePaths.add(paths.remove(paths.size()-1));
            invalidate();
        }
        else
        {

        }
    }

    public void onClickRedo ()
    {
        if (undonePaths.size()>0) 
        { 
            paths.add(undonePaths.remove(undonePaths.size()-1)); 
            invalidate();
        } 
        else 
        {

        }
    }
}

1 个答案:

答案 0 :(得分:4)

您只有一个m_Paint个对象,因此当调用onDraw时,它会使用您设置的最后一种颜色绘制所有路径。

您可以存储每条路径的颜色,并且在绘制路径之前必须设置颜色的内部onDraw

修改

以下是快速解决方案的大纲,晚上不是最优雅的解决方案:

  • HashMap,路径为键,颜色为值
  • onClickPenColorButton中将颜色保存到实例中说currentColor
  • touch_start中,您可以将currentColor的路径对象推送到HashMap
  • 修改onDraw以获取每个路径的颜色。 此代码仅用于说明,因此请根据需要进行修改。

    protected void onDraw(Canvas canvas)
    {                           
       for (Path p : paths)
       {  
          // Assuming your HashMap variable is pathColor
          m_Paint.setColor(pathColor.get(p));
    
          canvas.drawPath(p, m_Paint);
       }
    }