这里有多个涂鸦应用程序有一个撤消按钮。我没有实现这些,因为我的代码是不同的,但我已经看过这些概念。 I.E将点存储在一个数组中。画布不重绘图像
当程序检测到触摸事件:
@Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX(); //Gets the fingers x position
float touchY = event.getY(); //gets the fingers y position
PointF points = new PointF(); //init a new PointF
points.x = touchX; //store the coordinates in the Point object
points.y = touchY;
_pointList.add(points); //add this to the list of Points (array)
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
_path.moveTo(touchX, touchY); //Set the beginning of the next contour to the point (x,y)
//will start drawing from where the last point was
break;
case MotionEvent.ACTION_MOVE:
_path.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
break;
}
invalidate();
return true;
}
在理论上应该_pointList Array
捕获所有的触摸输入秩序。这很明显,因为控制台显示数组的大小。
在onDraw
方法中,它应该循环遍历a列表中的所有点。由于它包含用户在屏幕上进行交互的所有点,因此理论上它应该从内存中绘制线条。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (PointF points : _pointList) {
_path.moveTo(points.x, points.y);
_path.lineTo(points.x, points.y);
_canvas.drawPath(_path, _paint);
}
canvas.drawBitmap(_bitmap, 0, 0, _paint);
}
当应用程序运行时,我可以在屏幕上绘图,并且由于清除方法屏幕清除。
public void clear(){
_pointList.clear();// empty the list that stores the points
_bitmap = Bitmap.createBitmap(1000,1000,
Bitmap.Config.ARGB_8888);
_canvas = new Canvas(_bitmap);
_path = new Path();
_paint = new Paint(Paint.DITHER_FLAG);
//Added later..
_paint.setColor(Color.RED);
_paint.setAntiAlias(true);
_paint.setStyle(Paint.Style.STROKE);
//empties the screen
invalidate();
}
然而,在我的Undo方法,它应该放弃从_pointList
列表中的点(包含用户的X和Y触摸输入)之一。删除点后,屏幕应重新绘制内存中的所有行。
public void undo() {
Log.d("Number", "undo:" + _pointList.size() );
if (_pointList.size()>0){
_bitmap = Bitmap.createBitmap(1000,1000,
Bitmap.Config.ARGB_8888);
_canvas = new Canvas(_bitmap);
_path = new Path();
_paint = new Paint(Paint.DITHER_FLAG);
//Added later..
_paint.setColor(Color.RED);
_paint.setAntiAlias(true);
_paint.setStyle(Paint.Style.STROKE);
_pointList.remove(_pointList.size() - 1);
invalidate();
}
}
此方法具有与“清除”方法相同的效果,并且不重绘线,
我的其他办法,以撤销按钮是把位图到一个数组,但我敢肯定这会导致内存问题,因为它是一个动态程序。
问题:为什么'undo'方法中的'invalidate'调用不会更新屏幕?
更新:
整个代码:
--Draw--
package com.example.moynul.myapplication;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by moynu on 10/12/2015.
*/
public class Draw extends View {
private Paint _paint = new Paint();
private Path _path = new Path();
private Bitmap _bitmap;
private Canvas _canvas;
private List<PointF> _pointList = new ArrayList<PointF>();
public Draw(Context context) {
super(context);
init(null, 0);
}
public Draw(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs,0);
}
public Draw(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr);
}
private void init(AttributeSet attrs, int defStyleAttr) {
_paint.setColor(Color.RED);
_paint.setAntiAlias(true);
_paint.setStyle(Paint.Style.STROKE);
_bitmap = Bitmap.createBitmap (1080, 1920, Bitmap.Config.ARGB_8888);
_canvas = new Canvas(_bitmap);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX(); //Gets the fingers x position
float touchY = event.getY(); //gets the fingers y position
PointF points = new PointF(); //init a new PointF
points.x = touchX; //store the coordinates in the Point object
points.y = touchY;
_pointList.add(points); //add this to the list of Points (array)
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
_path.moveTo(touchX, touchY); //Set the beginning of the next contour to the point (x,y)
//will start drawing from where the last point was
break;
case MotionEvent.ACTION_MOVE:
_path.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
break;
}
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (PointF points : _pointList) {
_path.moveTo(points.x, points.y);
_path.lineTo(points.x, points.y);
_canvas.drawPath(_path, _paint);
}
canvas.drawBitmap(_bitmap, 0, 0, _paint);
}
public void clear(){
_pointList.clear();// empty the list that stores the points
_bitmap = Bitmap.createBitmap(1000,1000,
Bitmap.Config.ARGB_8888);
_canvas = new Canvas(_bitmap);
_path = new Path();
_paint = new Paint(Paint.DITHER_FLAG);
//Added later..
_paint.setColor(Color.RED);
_paint.setAntiAlias(true);
_paint.setStyle(Paint.Style.STROKE);
//empties the screen
invalidate();
}
public void undo() {
Log.d("Number", "undo:" + _pointList.size());
if (_pointList.size()>0){
_pointList.remove(_pointList.size() - 1);
_bitmap = Bitmap.createBitmap(1000,1000,
Bitmap.Config.ARGB_8888);
_canvas = new Canvas(_bitmap);
_path = new Path();
_paint = new Paint(Paint.DITHER_FLAG);
//Added later..
_paint.setColor(Color.RED);
_paint.setAntiAlias(true);
_paint.setStyle(Paint.Style.STROKE);
invalidate();
}
}
}
请上传全班同学的看法,这将有助于@RohitPatil的页面已经更新,以显示整个代码在我结束 –
解决。 – Moynul
你需要重新思考你的逻辑。在'onDraw()'方法中,当迭代点来更新路径时,首先'moveTo()'一个点,然后'lineTo()'同一点。这实际上什么都不做,这就是为什么你的图像在撤消之后变成空白。你能够绘制的唯一原因是因为你在'onTouchEvent()'中移动了Path。但是,在撤消操作中,您将重置路径,所以下一个'onDraw()'只是循环遍历点,对每个点都做同样的“无”,但没有在onTouchEvent中发生的路径更新)'。 –