Android自定义视图图形: 截图:
这不能保存最后的迹线,我想在位图上重绘,但效果不是很好。
屏幕截图:
代码:
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);
}
}
您遇到过同样的问题吗?
答案 0 :(得分:0)
我已经找到了解决方案,但是我不想以这种方式解决问题。我的目标是仅使用新的画布来解决问题。
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
变量
sX = 100
,sY = 100
eY = 130
,eY = 150
invalidate()
,因此将触发draw()
绘制线[100,100]至[130,150] sX = 130
,sY = 150
不是ACTION_DOWN点值 invalidate()
因此将触发draw()
绘制线[130,150]到[160,180] @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
startY
和endX
endY