2015-12-10 121 views
0

这里有多个涂鸦应用程序有一个撤消按钮。我没有实现这些,因为我的代码是不同的,但我已经看过这些概念。 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(); 
     } 
    } 
} 
+0

请上传全班同学的看法,这将有助于@RohitPatil的页面已经更新,以显示整个代码在我结束 –

+0

解决。 – Moynul

+0

你需要重新思考你的逻辑。在'onDraw()'方法中,当迭代点来更新路径时,首先'moveTo()'一个点,然后'lineTo()'同一点。这实际上什么都不做,这就是为什么你的图像在撤消之后变成空白。你能够绘制的唯一原因是因为你在'onTouchEvent()'中移动了Path。但是,在撤消操作中,您将重置路径,所以下一个'onDraw()'只是循环遍历点,对每个点都做同样的“无”,但没有在onTouchEvent中发生的路径更新)'。 –

回答

0

更改里面的onDraw()用于循环以下

canvas.drawPath(_path, _paint); 

希望它会工作

+0

此方法直接写入画布,而不是位图。它往往会减慢程序的速度,并在几次后崩溃,除非通过点击清除按钮清除数组。 – Moynul

0

Y您的onDraw方法有问题,您总是在相同的位置(0,0)上绘制_bitmap,而不是在路径上。下面我的代码替换您onDraw代码:

@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, points.x, points.y, _paint); 
    } 
} 
+0

drawBitmap方法使用由当前矩阵转换的指定颜料绘制指定的位图,其顶部/左侧角在(x,y)处。 - API。这导致程序现在在整个屏幕上绘制位图,关于用户位置。由于_pointList包含用户触摸输入。因此,为该数组中的每个点绘制一个位图。总之,这会导致很酷的3-D效果,但会减慢程序的速度。 – Moynul