3

我正在尝试在类似手指画的应用程序中实现个人的撤消/重做方式。

我综合了三个对象:Main 类(名为 ScorePadActivity)、相关的 Main Layout(带有按钮、菜单等,以及我在其中创建绘图的 View 对象),以及我所在的第三个名为 ArrayList 的对象编写撤消/重做代码。

问题是,当我按下撤消按钮时没有任何反应,但如果我再次“一次性”绘制任何内容并按下撤消,屏幕就会更新。如果我画了很多次,要看到屏幕上发生的任何变化,我必须按我画过的相同次数的撤消按钮。

似乎(如标题)当我将位图添加到数组列表时,最后一个元素在以前的索引中重复,并且由于某种奇怪的原因,每次我按下撤消按钮时,系统一次都可以,但开始重复直到下一次撤消。使用一系列System.out.println插入的代码来验证索引的增加。

现在,当我在屏幕上绘制某些东西时,数组列表会使用在调用touchup();motionEvent 中的方法后插入的代码进行更新

touch_up(); }
      this.arrayClass.incrementArray(mBitmap);
    mPath.rewind();
      invalidate();

并在 ArrayList 活动中;

public void incrementArray(Bitmap mBitmap) {
this._mBitmap=mBitmap;
_size=undoArray.size();
    undoArray.add(_size, _mBitmap);
    }

(删除所有日志以便清晰阅读)

ScorePadActivity 中的 undo 按钮调用 View 活动中的 undo 方法:

Button undobtn= (Button)findViewById(R.id.undo);
undobtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                mView.undo();
                }
        });

在查看活动中:

public void undo() {
this.mBitmap= arrayClass.undo();
 mCanvas = new Canvas(mBitmap); 
  mPath.rewind();
    invalidate();
}

调用 ArrayList 活动中的相对撤消方法:

public Bitmap undo() {
    // TODO Auto-generated method stub
    _size=undoArray.size();
                    if (_size>1) {
    undoArray.remove(_size-1);
_size=undoArray.size();
          _mBitmap = ((Bitmap) undoArray.get(_size-1)).copy(Bitmap.Config.ARGB_8888,true);
}
return _mBitmap;
    }

return mBitmap and invalidate:

由于我的英语不好,我制定了一个计划来使问题更清楚: 问题的通量

我试过用 HashMap,用一个简单的数组,我试过mPath.rewind();用等改变reset();new Path();但没有。为什么?

抱歉,答案很复杂,我想提前非常感谢您。最好的祝福

编辑

 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <LinearLayout
        android:id="@+id/buttonlayout"
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >

      some other layouts nested an buttons to form a upper toolbar


</LinearLayout>

    <RelativeLayout
        android:id="@+id/viewlayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@+id/buttonlayout"
        android:background="@drawable/desk_wood" >

      <com.example.android.touchexample.MyView
          android:id="@+id/viewout"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:layout_alignParentLeft="true"
          android:layout_alignParentTop="true" />



    </RelativeLayout>

</RelativeLayout>

这是主要活动 ScorePadActivity

public class ScorePadActivity extends Activity {


MyView mView;

public void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    mView = (MyView)findViewById(R.id.viewout);     
Button undobtn= (Button)findViewById(R.id.undo);
undobtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                mView.undo();
                }
        });

这是查看活动:

public class MyView extends View {


MyView myView;

Context context;
final ArrayClass arrayClass= new ArrayClass();

private Bitmap mBitmap;
private Bitmap savedBmp;
private static Canvas mCanvas;
private static Path mPath;
private static Paint mPaint;
/*
* some other variables here 
*/

public MyView(Context context) {
    super(context);
 }

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);
    mPaint = new Paint();
      mPaint.setAntiAlias(true);
        mPaint.setColor(color);
            mPaint.setStyle(Paint.Style.STROKE);
                mPaint.setStrokeJoin(Paint.Join.ROUND);
                mPaint.setStrokeCap(Paint.Cap.ROUND);
                mPaint.setStrokeWidth(bSize);
                    mPaint.setAlpha(255);
                        mPath = new Path();
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}
@Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap((int) bmWidth, (int) bmHeight,Bitmap.      Config.ARGB_8888);}
/*
 * here add a blank bitmap at the start of the array at index 0         
 */

arrayClass.incrementArray(mBitmap);
                mCanvas = new Canvas(mBitmap);
  }
public void onDraw(Canvas canvas) {

    canvas.save();  

    bx= (((width/mScaleFactor)-width)/2)+center;
    by= ((height/mScaleFactor)-height)/2;


    canvas.translate(mPosX, mPosY);
        canvas.scale(mScaleFactor, mScaleFactor);
            canvas.drawBitmap(penta, bx, by, null); 
                mCanvas.drawPath(mPath, mPaint);  
                canvas.drawBitmap(mBitmap, bx, by, null); 
                lastmPosX=mPosX;
                    lastmPosY=mPosY;
                        lastmScaleFactor=mScaleFactor;
                            canvas.restore();

  }
private void touch_start(float x, float y) {
      x=((x/mScaleFactor)-bx)-(mPosX/mScaleFactor);
      y=((y/mScaleFactor)-by)-(mPosY/mScaleFactor);
      mPath.rewind();
        mPath.moveTo(x, y);
            move=false;
                mX = x;
                    mY = y;
  }


  private void touch_move(float x, float y) {

      x=((x/mScaleFactor)-bx)-(mPosX/mScaleFactor);
      y=((y/mScaleFactor)-by)-(mPosY/mScaleFactor);
    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; 
                        move=true;
    }

  }

  private void touch_up() {

  mPath.lineTo(mX, mY);
        // mPath.rewind();
        }

 @Override
 public boolean onTouchEvent(MotionEvent ev) {
        x = ev.getX();
        y = ev.getY();


    switch (ev.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(); 
      // Here update the arraylist in the ArrayList activity
      this.arrayClass.incrementArray(mBitmap);
            mPath.rewind();
                invalidate();

      break;}

  return true;
  }

 /*
 * more methods here
*/      switch (ev.getAction()) {

    case MotionEvent.ACTION_DOWN:


    public void undo() {
            // Here recall the last mBitmap from Arraylist activity
                this.mBitmap= arrayClass.undo();
                    mCanvas = new Canvas(mBitmap);  
                        mPath.rewind();
                invalidate();
}
}

这是我的 ArrayList 活动:

public class ArrayClass {

ArrayList<Bitmap> undoArray =new ArrayList<Bitmap>();
private int _size;
private Bitmap _mBitmap;

public void incrementArray(Bitmap mBitmap) {
    this._mBitmap=mBitmap;
        _size=undoArray.size();
            // undoArray.add(_size, _mBitmap);
                               undoArray.add(_size, Bitmap.createBitmap(_mBitmap));
            }

public Bitmap undo() {
    // TODO Auto-generated method stub
    _size=undoArray.size();
if (_size>1) {
        undoArray.remove(_size-1);
        _size=undoArray.size();
_mBitmap = ((Bitmap) undoArray.get(_size-1)).copy(Bitmap.Config.ARGB_8888,true);
            }
return _mBitmap;
    }

public Bitmap redo() {
    // TODO 
    return null;
}
}

再次感谢

4

1 回答 1

0

这里的解决方案,以这种方式编辑 ArrayClass:

public class ArrayClass {

ArrayList<Bitmap> undoArray =new ArrayList<Bitmap>();
private int _size;
private Bitmap _mBitmap;

public void incrementArray(Bitmap mBitmap) {
this._mBitmap=mBitmap;
    _size=undoArray.size();
        // undoArray.add(_size, _mBitmap); replace with:
                           undoArray.add(_size, Bitmap.createBitmap(_mBitmap));
        }

public Bitmap undo() {
 // TODO Auto-generated method stub
_  size=undoArray.size();
if (_size>1) {
    undoArray.remove(_size-1);
    _size=undoArray.size();
      _mBitmap = ((Bitmap) undoArray.get(_size-1)).copy(Bitmap.Config.ARGB_8888,true);
        }
return _mBitmap;
}

public Bitmap redo() {
// TODO 
return null;
}
}
于 2012-11-27T02:14:48.760 回答