简体   繁体   English

Android自定义视图绘图

[英]Android custom view drawing

Android custom view drawing: Screenshot: Android自定义视图绘图:屏幕截图:

在此输入图像描述

This can't save the last trace, i want to redraw on a bitmap but the effect is not very good. 这不能保存最后一个跟踪,我想重绘一个位图,但效果不是很好。

Screenshot: 截图:

在此输入图像描述

code: 码:

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

Have you ever encountered the same problem? 你遇到过同样的问题吗?

I have found a solution, but I don't want to solve the problem in this way. 我找到了解决方案,但我不想以这种方式解决问题。 My goal is to solve the problem with only the new canvas. 我的目标是只用新画布来解决问题。

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

or 要么

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

You should update the sX sY variable, when your finger is moving 您应该更新sX sY变量,当你的手指移动

  1. ACTION_DOWN point is [100, 100] sX = 100 , sY = 100 ACTION_DOWN点为[100,100] sX = 100sX = 100 sY = 100
  2. ACTION_MOVE now finger is locating at [130, 150] eY = 130 , eY = 150 ACTION_MOVE现在手指位于[130,150] eY = 130eY = 150
  3. invalidate() so will trigger draw() draw line [100, 100] to [130, 150] invalidate()所以会触发draw()绘制线[100,100]到[130,150]
  4. finger continue to move 手指继续移动
  5. ACTION_MOVE now the start is [130, 150] sX = 130 , sY = 150 not ACTION_DOWN point value ACTION_MOVE现在开始是[130,150] sX = 130sX = 130 sY = 150 而不是ACTION_DOWN点值
  6. ACTION_MOVE now finger is locating at [160, 180] ACTION_MOVE现在手指位于[160,180]
  7. invalidate() so will trigger draw() draw line [130, 150] to [160, 180] invalidate()所以会触发draw()绘制线[130,150]到[160,180]
  8. continue do the same thing ..... 继续做同样的事情.....
@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;
}

i have not Run the code, but maybe you have understood what i mean. 我没有运行代码,但也许你已经明白了我的意思。

you should update both startX startY , and endX endY 你应该更新startX startYendX endY

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM