java - 如何防止onDraw的Paint影响ArrayList中的所有矩形?
问题描述
我为绘图应用程序编写了一些代码,以便在 Android 环境中学习 Java。我可以选择手绘、矩形或椭圆形。我还可以更改 Paint 属性,例如线宽、颜色等。
为了防止形状消失,每次绘制新形状时,都会将其添加到 ArrayList 或 ArrayList (ovals)
但是,当我使用其他一些代码来更改例如线宽或填充时,它会影响所有已经存在的形状,而不仅仅是我当前正在绘制的形状。
如果没有数组列表,如果我从绘制矩形切换到椭圆,形状就会消失。
float pointX;
float pointY;
float startX;
float startY;
private ArrayList<Rect> rectangles = new ArrayList<Rect>(); //rectangle array
@Override
protected void onDraw(Canvas canvas) {
// draw background
canvas.drawBitmap(bitmap, 0, 0, paintScreen);
for(Rect rect : rectangles){
canvas.drawRect(rect,paintLine);
//other additional drawMethods exist here for ovals and freehand pathmap
@Override
public boolean onTouchEvent(MotionEvent event) {
if(rectangleDraw){
pointX = event.getX();
pointY = event.getY();
// Checks for the event that occurs
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = pointX;
startY = pointY;
return true;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
rectangles.add(new Rect((int)startX, (int)startY, (int)pointX, (int)pointY));
break;
default:
return false;
}
// Force a view to draw again
invalidate();
return true;
}
问题是添加到数组列表中的形式为 rectangle.add(new Rect(startX,startY,pointX,pointY),并且 Paint 没有第五个参数来保存该特定矩形的样式选择,也不允许这样做。我现在假设 onDraw 方法采用整个数组列表,并将一个当前的 Paint 样式应用于整个事物。
那么我应该使用什么替代方案?
我尝试使用 Hashmap 将 Rect 存储为键,将 Paint 对象存储为值,然后在 onDraw() 中对其进行迭代,但是当绘制的设置发生更改时,它仍然会不断切换样式。(参考图片)
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, paintScreen);
for(Rect rect : rectanglePaint.keySet()){
canvas.drawRect(rect, rectanglePaint.get(rect));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(rectangleDraw){
pointX = event.getX();
pointY = event.getY();
// Checks for the event that occurs
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = pointX;
startY = pointY;
return true;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
Rect rectX = (new Rect((int)startX, (int)startY, (int)pointX, (int)pointY));
rectanglePaint.put(rectX, paintLine);
break;
default:
return false;
}
// Force a view to draw again
invalidate();
return true;
}
解决方案
好吧,看来我设法解决了自己的问题。除了使用 HashMap 之外,似乎关键是在触摸事件中创建一个新的 Paint 实例,将其作为值附加到 hashmap 上。
所以像这样的东西(在所有的吸气剂中还没有完全准备好,但是有效):
case MotionEvent.ACTION_UP:
Paint paintRectangle = new Paint();
paintRectangle.setAntiAlias(true);
paintRectangle.setColor(paintLine.getColor());
paintRectangle.setStyle(Paint.Style.STROKE);
paintRectangle.setStrokeWidth(paintLine.getStrokeWidth());
paintRectangle.setStrokeCap(Paint.Cap.ROUND);
Rect rectX = (new Rect((int)startX, (int)startY, (int)pointX, (int)pointY));
rectanglePaint.put(rectX, paintRectangle);
break;
推荐阅读
- r - 从回归中绘制拟合值
- swiftui - 为什么我不能强制解开我的 $string 以用作 TextField 值?
- sql - SQL查找最后3个相同状态的记录
- javascript - Angular2 - 步进器和浏览器历史的按钮
- python - macOS Big Sur 上没有名为 pip 的模块
- android - 使用证书固定或 CA 证书?
- python - 在 Desktop-Python 上自动推送通知程序
- html - 主流 CSS
- tailwind-css - 如何在 Tailwind 中单独绝对定位最后一项?
- javascript - 在 Node.js 中将 PNG 与 GIF 组合的问题