gpt4 book ai didi

java - Android自定义 View 更新 View 的指定部分

转载 作者:太空宇宙 更新时间:2023-11-04 11:18:13 25 4
gpt4 key购买 nike

我通过从AppCompatImageView扩展一个类来实现一个绘画应用程序,它工作得很好,但是当绘制很多路径时,它的速度会降低

是否可以在绘制任何新路径时,只绘制添加到 View 中的新路径?

也就是说,只需更新 View 的特定部分即可,而不必每次都更新全部 View 。

PaintView.java

import android.content.Context;
import android.graphics.*;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Stack;


public class PaintView extends AppCompatImageView implements View.OnTouchListener {

private int defaultColor = 0xffff0000;
private int defaultLineStrokeWidth = 4;
private int defaultAlpha = 255;
private int currentPathIndex = 0;
private boolean isTouchDown = false;
private boolean showBounds = false;
private boolean isDeleteMode = false;

private Paint linePaint;
private Paint rectPaint;
private Stack<PathHolder> paths;
private Stack<PathHolder> memoryList;

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

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

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

private void init() {
setOnTouchListener(this);

setBackgroundColor(Color.WHITE);

linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setStrokeWidth(defaultLineStrokeWidth);
linePaint.setDither(true);
linePaint.setAntiAlias(true);
linePaint.setColor(Color.BLACK);
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeCap(Paint.Cap.ROUND);
linePaint.setStrokeJoin(Paint.Join.ROUND);
linePaint.setPathEffect(new CornerPathEffect(10));

rectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
rectPaint.setStrokeWidth(0.5f);
rectPaint.setAntiAlias(true);
rectPaint.setColor(Color.RED);
rectPaint.setStyle(Paint.Style.STROKE);

paths = new Stack<>();
memoryList = new Stack<>();
}

public void setPaintColor(@ColorInt int color) {
defaultColor = color;
}

public void showBounds(boolean show) {
showBounds = show;
invalidate();
}

public void setDeleteMode(boolean deleteMode) {
this.isDeleteMode = deleteMode;
invalidate();
}

public void setLineStrokeWidth(int width) {
if (width > 0) {
defaultLineStrokeWidth = width;
} else {
Log.e("GestureView", "Stroke width can't be zero or less.");
}
}

public void setLineAlpha(@IntRange(from = 0, to = 255) int alpha) {
defaultAlpha = alpha;
}

public int getDefaultLineStrokeWidth() {
return defaultLineStrokeWidth;
}

public void clearScreen() {
currentPathIndex = 0;
paths.clear();
memoryList.clear();

invalidate();
}

@Override
protected void onDraw(Canvas canvas) {
if (paths.size() > 0) {
for (int i = 0; i < paths.size(); i++) {
paths.get(i).setColor(paths.get(i).getColor() != 0 ? paths.get(i).getColor() : defaultColor);
paths.get(i).setStrokeWidth(paths.get(i).getStrokeWidth() != 0 ? paths.get(i).getStrokeWidth() : defaultLineStrokeWidth);
paths.get(i).setAlpha(paths.get(i).getAlpha() != 0 ? paths.get(i).getAlpha() : defaultAlpha);

linePaint.setColor(paths.get(i).getColor());
linePaint.setStrokeWidth(paths.get(i).getStrokeWidth());
linePaint.setAlpha(paths.get(i).getAlpha());

canvas.drawPath(paths.get(i).getPath(), linePaint);
paths.get(i).getPath().computeBounds(paths.get(i).getRect(), true);

if (showBounds && (!isTouchDown || currentPathIndex != i)) {
canvas.drawRect(paths.get(i).getRect(), rectPaint);
}
}
}
}

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (isDeleteMode) {
for (int i = 0; i < paths.size(); i++) {
if (RectF.intersects(paths.get(i).getRect(), new RectF(motionEvent.getX(), motionEvent.getY(), motionEvent.getX(), motionEvent.getY()))) {
memoryList.push(paths.get(i));
paths.remove(i);
currentPathIndex--;
invalidate();
break;
}
}
} else {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
isTouchDown = true;

Path path = new Path();
path.moveTo(motionEvent.getX(), motionEvent.getY());

RectF rectF = new RectF();
path.computeBounds(rectF, true);

PathHolder pathHolder = new PathHolder();
pathHolder.setPath(path);
pathHolder.setRect(rectF);

paths.add(currentPathIndex, pathHolder);
break;

case MotionEvent.ACTION_UP:
isTouchDown = false;
paths.get(currentPathIndex).getPath().lineTo(motionEvent.getX(), motionEvent.getY());
currentPathIndex++;
invalidate();
break;

case MotionEvent.ACTION_MOVE:
paths.get(currentPathIndex).getPath().lineTo(motionEvent.getX(), motionEvent.getY());
invalidate();
break;
}
}
return true;
}

public void undo() {
if (paths.isEmpty()) {
return;
}
memoryList.push(paths.pop());
currentPathIndex--;
invalidate();
}

public void redo() {
if (memoryList.isEmpty()) {
return;
}
paths.push(memoryList.pop());
currentPathIndex++;
invalidate();
}

public Bitmap getCaptureBitmap() {
setDrawingCacheEnabled(true);
return getDrawingCache();
}

public void saveCaptureTo(String path, int quality) {
Bitmap b = getCaptureBitmap();
try {
b.compress(Bitmap.CompressFormat.PNG, quality, new FileOutputStream(path));
} catch (FileNotFoundException e) {
Log.e(GestureView.class.getSimpleName(), e.getMessage());
}
}
}

最佳答案

所以当你在 Canvas 上绘制时,你必须再次绘制整个 Canvas 。根据我的理解,每次调用 onDraw 时,您基本上都是在一张新纸上绘图(60ps)

关于java - Android自定义 View 更新 View 的指定部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45218761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com