Android自定义视图绘图

时间:2019-04-26 07:45:55

标签: android canvas touch android-bitmap

Android自定义视图图形: 截图:

enter image description here

这不能保存最后的迹线,我想在位图上重绘,但效果不是很好。

屏幕截图:

enter image description here

代码:

public class CustomView extends View {

private float sX, sY, eX, eY;

private Paint paint = new Paint();
private Canvas canvas = new Canvas();
private Bitmap bitmap;

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
    canvas.setBitmap(bitmap);
    setBackgroundColor(Color.WHITE);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            eX = event.getX();
            eY = event.getY();
            canvas.drawLine(sX, sY, eX, eY, paint);
            break;
        case MotionEvent.ACTION_DOWN:
            sX = event.getX();
            sY = event.getY();
            break;
        case MotionEvent.ACTION_UP:
            break;
    }
    invalidate();
    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawBitmap(bitmap, getMatrix(), null);
}
}

您遇到过同样的问题吗?

2 个答案:

答案 0 :(得分:0)

我已经找到了解决方案,但是我不想以这种方式解决问题。我的目标是仅使用新的画布来解决问题。

screenshot

public class CustomView extends View {

private float sX, sY, eX, eY;

private Paint paint = new Paint();
private Canvas canvas = new Canvas();
private Bitmap bitmap;

public CustomView(Context context) {
    super(context);
    init();
}

public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    paint.setColor(Color.RED);
    paint.setStrokeWidth(3);
    paint.setAntiAlias(true);
    paint.setDither(true);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStyle(Paint.Style.STROKE);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
    canvas.setBitmap(bitmap);
    setBackgroundColor(Color.WHITE);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            eX = event.getX();
            eY = event.getY();
            break;
        case MotionEvent.ACTION_DOWN:
            sX = event.getX();
            sY = event.getY();
            break;
        case MotionEvent.ACTION_UP:
            canvas.drawLine(sX, sY, eX, eY, paint);
            break;
    }
    invalidate();
    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawBitmap(bitmap, getMatrix(), null);
    canvas.drawLine(sX, sY, eX, eY, paint);
}
}

public class CustomView extends View {

private Paint paint = new Paint();
private List<Path> cache = new ArrayList<>();
private Path currentPath;

public CustomView(Context context) {
    super(context);
    init();
}

public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    paint.setColor(Color.RED);
    paint.setStrokeWidth(3);
    paint.setAntiAlias(true);
    paint.setDither(true);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStyle(Paint.Style.STROKE);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            if (currentPath != null) {
                currentPath.eX = event.getX();
                currentPath.eY = event.getY();
            }
            break;
        case MotionEvent.ACTION_DOWN:
            currentPath = new Path();
            currentPath.sX = event.getX();
            currentPath.sY = event.getY();
            break;
        case MotionEvent.ACTION_UP:
            if (currentPath != null) {
                cache.add(currentPath);
                currentPath = null;
            }
            break;

    }
    invalidate();
    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    for (Path path : cache) {
        canvas.drawLine(path.sX, path.sY, path.eX, path.eY, paint);
    }
    if (currentPath == null) return;
    canvas.drawLine(currentPath.sX, currentPath.sY, currentPath.eX, currentPath.eY, paint);
}

static class Path {
    float sX;
    float sY;
    float eX;
    float eY;
}
}

答案 1 :(得分:0)

当手指移动时,您应该更新sX sY变量

  1. ACTION_DOWN点为[100,100] sX = 100sY = 100
  2. ACTION_MOVE现在手指位于[130,150] eY = 130eY = 150
  3. invalidate(),因此将触发draw()绘制线[100,100]至[130,150]
  4. 手指继续移动
  5. ACTION_MOVE现在开始是[130,150] sX = 130sY = 150 不是ACTION_DOWN点值
  6. ACTION_MOVE现在手指位于[160,180]
  7. invalidate()因此将触发draw()绘制线[130,150]到[160,180]
  8. 继续做同样的事情.....
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            eX = event.getX();
            eY = event.getY();
            invalidate()
            sX = eX;
            sY = eY;
            break;
        case MotionEvent.ACTION_DOWN:
            sX = event.getX();
            sY = event.getY();
            break;
        case MotionEvent.ACTION_UP:
            canvas.drawLine(sX, sY, eX, eY, paint);
            break;
    }
    //invalidate();
    return true;
}

我还没有运行代码,但是也许您已经理解了我的意思。

您应该同时更新startX startYendX endY