在paint undo redo中创建新对象示例-Android

在paint undo redo中创建新对象示例-Android,android,object,view,android-canvas,paint,Android,Object,View,Android Canvas,Paint,我创建了一个关于ANdroid中撤销重做绘制的示例项目 单击每个按钮以更改绘制颜色时,我会初始化一个新对象,例如: dp = new DrawingPanel(MainActivity.this, Color.RED); 带有要设置的DrawingPanel dp和颜色 但是所有的油漆都换成了新的颜色,虽然以前的是另一种颜色 我怎样才能解决这个问题 activity_main.xml <LinearLayout xmlns:android="http://schemas.android.

我创建了一个关于ANdroid中撤销重做绘制的示例项目

单击每个按钮以更改绘制颜色时,我会初始化一个新对象,例如:

dp = new DrawingPanel(MainActivity.this, Color.RED);
带有要设置的DrawingPanel dp和颜色

但是所有的油漆都换成了新的颜色,虽然以前的是另一种颜色

我怎样才能解决这个问题

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#A52A2A"
    android:gravity="center_horizontal"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/Undo"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Undo" />

    <Button
        android:id="@+id/Redo"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Redo" />
</LinearLayout>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/btnRed"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="RED" />

    <Button
        android:id="@+id/btnBlue"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="BLUE" />

    <Button
        android:id="@+id/btnYELLOW"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="YELLOW" />

    <Button
        android:id="@+id/btnGreen"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="GREEN" />
</LinearLayout>

<FrameLayout
    android:id="@+id/frameLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#CCC" >
</FrameLayout>

MainActivity.java

public class MainActivity extends Activity {

private ArrayList<Path> undonePaths = new ArrayList<Path>();
private ArrayList<Path> paths = new ArrayList<Path>();

FrameLayout frmLayout;
DrawingPanel dp;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    frmLayout = (FrameLayout) findViewById(R.id.frameLayout);
    dp = new DrawingPanel(this, Color.BLACK);
    frmLayout.addView(dp);

    initChangeColor();
    initUndoRedo();

}

private void initUndoRedo() {

    ((Button) findViewById(R.id.Undo))
            .setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    if (paths.size() > 0) {
                        undonePaths.add(paths.remove(paths.size() - 1));
                        dp.invalidate();
                    }
                }
            });

    ((Button) findViewById(R.id.Redo))
            .setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (undonePaths.size() > 0) {
                        paths.add(undonePaths.remove(undonePaths.size() - 1));
                        dp.invalidate();
                    }
                }
            });

}

private void initChangeColor() {

    findViewById(R.id.btnRed).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            dp = new DrawingPanel(MainActivity.this, Color.RED);
            frmLayout.addView(dp);
        }
    });

    findViewById(R.id.btnBlue).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            dp = new DrawingPanel(MainActivity.this, Color.BLUE);
            frmLayout.addView(dp);
        }
    });

    findViewById(R.id.btnYELLOW).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            dp = new DrawingPanel(MainActivity.this, Color.YELLOW);
            frmLayout.addView(dp);
        }
    });

    findViewById(R.id.btnGreen).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            dp = new DrawingPanel(MainActivity.this, Color.GREEN);
            frmLayout.addView(dp);
        }
    });

}

public class DrawingPanel extends View implements OnTouchListener {

    private Canvas mCanvas;
    private Path mPath;
    private Paint mPaint, circlePaint, outercirclePaint;

    private float xleft, xright, xtop, xbottom;

    public DrawingPanel(Context context, int colorPaint) {
        super(context);

        setFocusable(true);
        setFocusableInTouchMode(true);

        this.setOnTouchListener(this);

        circlePaint = new Paint();
        mPaint = new Paint();
        outercirclePaint = new Paint();

        outercirclePaint.setAntiAlias(true);
        circlePaint.setAntiAlias(true);

        mPaint.setAntiAlias(true);
        mPaint.setColor(colorPaint);

        outercirclePaint.setColor(0x44FFF000);
        circlePaint.setColor(0xAADD5522);
        outercirclePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStyle(Paint.Style.FILL);

        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(20);

        outercirclePaint.setStrokeWidth(6);
        mCanvas = new Canvas();
        mPath = new Path();
        paths.add(mPath);
    }

    @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 (Path p : paths) {
            canvas.drawPath(p, mPaint);
        }

    }

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 0;

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.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) {
            mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
    }

    private void touch_up() {
        mPath.lineTo(mX, mY);
        mCanvas.drawPath(mPath, mPaint);
        mPath = new Path();
        paths.add(mPath);
    }

    @Override
    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;
    }
}
}
公共类MainActivity扩展活动{
private ArrayList undonePaths=new ArrayList();
私有ArrayList路径=新ArrayList();
框架布局FRM布局;
绘图板dp;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frmLayout=(FrameLayout)findviewbyd(R.id.FrameLayout);
dp=新绘图面板(此颜色为黑色);
frmLayout.addView(dp);
initChangeColor();
initUndoRedo();
}
私有void initUndoRedo(){
((按钮)findViewById(R.id.Undo))
.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
if(path.size()>0){
undonePaths.add(path.remove(path.size()-1));
dp.invalidate();
}
}
});
((按钮)findViewById(R.id.Redo))
.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
如果(撤消路径大小()>0){
add(undonePaths.remove(undonePaths.size()-1));
dp.invalidate();
}
}
});
}
私有void initChangeColor(){
findviewbyd(R.id.btnRed).setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
dp=新绘图面板(MainActivity.this,颜色为红色);
frmLayout.addView(dp);
}
});
findviewbyd(R.id.btnBlue).setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
dp=新绘图面板(MainActivity.this,颜色为蓝色);
frmLayout.addView(dp);
}
});
findviewbyd(R.id.btnYELLOW).setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
dp=新绘图面板(MainActivity.this,颜色为黄色);
frmLayout.addView(dp);
}
});
findviewbyd(R.id.btnGreen).setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
dp=新绘图面板(MainActivity.this,颜色为绿色);
frmLayout.addView(dp);
}
});
}
公共类DrawingPanel扩展了视图实现OnTouchListener{
私人帆布mCanvas;
专用路径mPath;
私人油漆mPaint、电路漆、外部油漆;
私人浮动xleft、xright、xtop、xbottom;
公共绘图面板(上下文,int colorPaint){
超级(上下文);
设置聚焦(真);
setFocusableInTouchMode(真);
this.setOnTouchListener(this);
circlePaint=新油漆();
mPaint=新油漆();
outercreclaint=新油漆();
outerClipaint.setAntiAlias(true);
circlePaint.setAntiAlias(真);
mPaint.setAntiAlias(true);
mPaint.setColor(彩色涂料);
outerClipaint.setColor(0x44FFF000);
circlePaint.setColor(0xAADD5522);
外部油漆.设置样式(油漆.样式.笔划);
循环油漆.设置样式(油漆.样式.填充);
mPaint.setStyle(油漆、样式、笔划);
mPaint.setStrokeJoin(油漆.连接.圆形);
mPaint.setStrokeCap(油漆盖圆形);
mPaint.设定行程宽度(20);
外涂层设置行程宽度(6);
mCanvas=新画布();
mPath=新路径();
路径。添加(mPath);
}
@凌驾
已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh){
super.onSizeChanged(w,h,oldw,oldh);
}
@凌驾
受保护的void onDraw(画布){
用于(路径p:路径){
画布绘制路径(p,mPaint);
}
}
私人浮动mX,我的;
专用静态最终浮动接触公差=0;
专用无效触摸启动(浮动x、浮动y){
mPath.reset();
移动到(x,y)的速度;
mX=x;
mY=y;
}
私有无效触摸移动(浮动x、浮动y){
float dx=Math.abs(x-mX);
float dy=Math.abs(y-mY);
如果(dx>=接触公差| | dy>=接触公差){
兆帕四分之一秒(mX,mY,(x+mX)/2,(y+mY)/2);
mX=x;
mY=y;
}
}
私人空间修补(){
mPath.lineTo(mX,mY);
mCanvas.drawPath(mPath,mPaint);
mPath=新路径();
路径。添加(mPath);
}
@凌驾
公共布尔onTouch(视图arg0,运动事件){
float x=event.getX();
float y=event.getY();
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
触摸启动(x,y);
使无效();
打破
case MotionEvent.ACTION\u移动:
触摸移动(x,y);
使无效();
打破
case MotionEvent.ACTION\u UP:
润色;
使无效();
打破
}
返回true;
}
}
}

您还必须将颜色保存到撤消历史记录中。我认为最好的方法是创建一个包含路径和颜色的类并使用它们。我想它可能看起来像这样(但我还没有测试过它,所以如果它需要一些调整的话,不要开枪打我)

它是Path类的扩展,该类也有一个用于保存颜色的公共变量。然后用于存储您将使用的历史记录:

private ArrayList<MyPath> undonePaths = new ArrayList<MyPath>();
private ArrayList<MyPath> paths = new ArrayList<MyPath>();
private ArrayList undonePaths=n
private ArrayList<MyPath> undonePaths = new ArrayList<MyPath>();
private ArrayList<MyPath> paths = new ArrayList<MyPath>();