3

Android で Canvas クラスを使用するのはこれが初めてです。

私が欲しいのは、キャンバスにさまざまな色で線を引くことです。解決できない問題があります。

最初の線を黒で描画し、色を赤に変更して 2 番目の線を赤で描画しようとすると、最初に描画された黒の線が赤に変わります。

私が使用したコードは次のとおりです。

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 
        {

        }
    }
}
4

2 に答える 2

4

オブジェクトは 1 つしかないm_Paintため、onDrawが呼び出されると、最後に設定した色を使用してすべてのパスが描画されます。

各パスの色を保存でき、パスを描画するonDrawに色を設定する必要があります

編集

これが簡単な解決策の概要です。夜は最もエレガントなものではありません。

  • HashMapパスがキーで色が値のA
  • onClickPenColorButton色をインスタンスに保存すると言うcurrentColor
  • で、パス オブジェクトをにtouch_startプッシュできます。currentColorHashMap
  • 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);
       }
    }
    
于 2013-01-31T12:29:44.850 に答える