我正在使用Java在Android Studio中设计一个绘图应用程序。我的activity_main. xml中有一个''按钮和'-'按钮。每当我单击这些按钮时,笔的大小会增加或减少,但它也会增加或减少我已经在画布上绘制的内容。这不应该发生,为什么会发生这种情况?
增加/减少函数的代码片段:
public void increasePenSize() {
float currentStrokeWidth = paint.getStrokeWidth();
float newStrokeWidth = currentStrokeWidth + 2f;
paint.setStrokeWidth(newStrokeWidth);
}
public void decreasePenSize() {
float currentStrokeWidth = paint.getStrokeWidth();
float newStrokeWidth = currentStrokeWidth - 2f;
paint.setStrokeWidth(newStrokeWidth);
}
完整代码:
package com.example.sketch_1;
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.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class CanvasView extends View
{
Context context;
private int width, height;
private Bitmap bitmap;
private Paint paint;
private Path path;
private Canvas canvas;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
// Add variables to keep track of previous paths and their colors
private List<Path> paths = new ArrayList<>();
private List<Integer> colors = new ArrayList<>();
private int currentColor = Color.BLACK;
public CanvasView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context = context;
path = new Path();
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(4f);
}
public void changePenColor(String color) {
switch (color) {
case "Black":
currentColor = Color.BLACK;
break;
case "Brown":
currentColor = Color.rgb(79, 30, 14);
break;
case "Blue":
currentColor = Color.BLUE;
break;
case "Cyan":
currentColor = Color.CYAN;
break;
case "Red":
currentColor = Color.RED;
break;
case "Orange":
currentColor = Color.rgb(255, 165, 0);
break;
case "Yellow":
currentColor = Color.YELLOW;
break;
case "Dark Green":
currentColor = Color.rgb(0, 100, 0);
break;
case "Light Green":
currentColor = Color.rgb(57, 252, 3);
break;
case "Pink":
currentColor = Color.rgb(250, 10, 174);
break;
case "Magenta":
currentColor = Color.rgb(212, 0, 255);
break;
case "Purple":
currentColor = Color.rgb(128, 0, 128);
break;
case "Eraser":
currentColor = Color.WHITE;
break;
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
}
public void startTouch(float x, float y)
{
// path.reset();
path = new Path();
path.moveTo(x, y);
mX = x;
mY = y;
// Add new path to list of paths and their colors
paths.add(path);
colors.add(currentColor);
}
public void moveTouch(float x, float y)
{
float dx = Math.abs(x-mX);
float dy = Math.abs(y-mY);
if(dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
{
path.quadTo(mX, mY, (x+mX)/2, (y+mY)/2);
mX = x;
mY = y;
}
}
// Function to clear the canvas
public void clearCanvas()
{
paths.clear();
colors.clear(); // Clears all the colors from the array
bitmap.eraseColor(Color.TRANSPARENT);
invalidate();
}
// Functions for increasing and decreasing pen size
public void increasePenSize() {
float currentStrokeWidth = paint.getStrokeWidth();
float newStrokeWidth = currentStrokeWidth + 2f;
paint.setStrokeWidth(newStrokeWidth);
}
public void decreasePenSize() {
float currentStrokeWidth = paint.getStrokeWidth();
float newStrokeWidth = currentStrokeWidth - 2f;
paint.setStrokeWidth(newStrokeWidth);
}
// Text box function
// public void showTextBox() {
// // Create a new EditText object
// EditText textBox = new EditText(getContext());
//
// // Set its layout parameters
// LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
// LinearLayout.LayoutParams.MATCH_PARENT,
// LinearLayout.LayoutParams.WRAP_CONTENT
// );
// textBox.setLayoutParams(params);
//
// // Add the text box to the layout
// LinearLayout layout = findViewById(R.id.btn_text_layout); // Replace with the ID of your layout
// layout.addView(textBox);
// }
// Handles all color changes from this single method function
// Not being used right now
// public void setPenColor(int color) {
// paint.setColor(color);
// }
public void upTouch()
{
path.lineTo(mX, mY);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Draw all paths with their respective colors
for (int i = 0; i < paths.size(); i++) {
paint.setColor(colors.get(i));
canvas.drawPath(paths.get(i), paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Get the x and y coordinates of the touch event
float x = event.getX();
float y = event.getY();
// Check the action of the touch event
switch(event.getAction())
{
// If the touch event is a down action
case MotionEvent.ACTION_DOWN:
// Call the startTouch method and pass in the x and y coordinates
startTouch(x, y);
// Invalidate the view to trigger a redraw
invalidate();
break;
// If the touch event is a move action
case MotionEvent.ACTION_MOVE:
// Call the moveTouch method and pass in the x and y coordinates
moveTouch(x, y);
// Invalidate the view to trigger a redraw
invalidate();
break;
// If the touch event is an up action
case MotionEvent.ACTION_UP:
// Call the upTouch method
upTouch();
// Invalidate the view to trigger a redraw
invalidate();
break;
}
// Return true to indicate that the event was handled
return true;
}
}
我期望增加和减少功能只影响将要绘制的内容,而不是画布上已经绘制的内容。我不确定为什么它会影响画布上的所有内容。
这变得更加复杂。你目前正在将所有数据添加到路径中。无论当前设置了什么笔,该路径都会绘制一次。最简单的方法是不使用这样的数据结构:
class DrawingData {
public Path path;
public int strokeWidth;
}
不是存储单个Path,而是存储一个List。每当大小发生变化时,向列表中添加一个新的DrawingData。然后在onDraw中,遍历列表并绘制所有这些,每次设置strokeWidth。