2015-12-10 117 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