画布不会重绘图像

时间:2015-12-10 22:41:52

标签: android canvas android-bitmap

这里有多个涂鸦应用程序都有一个撤消按钮。我没有实现这些,因为我的代码不同,但我已经看过了这些概念。 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 _pointList列表中的所有点。由于它包含用户在屏幕上交互的所有点,因此理论上它应该从内存中绘制线条。

  @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();
}

但是,在我的撤销方法中,它应该从_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();
    }
}

此方法与' clear'具有相同的效果。方法,不重绘行,

我撤消按钮的其他替代方法是将位图放入数组中,但我确信这会导致内存问题,因为它是一个动态程序。

问题:为什么'无效'来自'撤消'方法更新屏幕?

更新

整个代码:

- 画图 -

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();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

在onDraw()for for循环

中更改
canvas.drawPath(_path, _paint);

希望它能运作

答案 1 :(得分:0)

您的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);
    }
}