Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android自定义视图更新视图的指定部分_Java_Android_Draw_Android Custom View - Fatal编程技术网

Java Android自定义视图更新视图的指定部分

Java Android自定义视图更新视图的指定部分,java,android,draw,android-custom-view,Java,Android,Draw,Android Custom View,我通过从AppCompatImageView扩展一个类来实现一个绘画应用程序,它工作得很好,但是当绘制很多路径时,它的速度会降低 绘制任何新路径时,是否可以只绘制添加到视图中的新路径 换句话说,只需更新视图的特定部分,而不必每次都更新所有视图 PaintView.java import android.content.Context; import android.graphics.*; import android.support.annotation.ColorInt; import and

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

绘制任何新路径时,是否可以只绘制添加到视图中的新路径

换句话说,只需更新视图的特定部分,而不必每次都更新所有视图

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());
      }
   }
}
导入android.content.Context;
导入android.graphics.*;
导入android.support.annotation.ColorInt;
导入android.support.annotation.IntRange;
导入android.support.v7.widget.AppCompatImageView;
导入android.util.AttributeSet;
导入android.util.Log;
导入android.view.MotionEvent;
导入android.view.view;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.util.Stack;
公共类PaintView扩展AppCompatImageView实现View.OnTouchListener{
私有int defaultColor=0xffff0000;
private int defaultLineStrokeWidth=4;
私有int defaultAlpha=255;
私有int currentPathIndex=0;
private boolean isTouchDown=false;
私有布尔showBounds=false;
私有布尔值isDeleteMode=false;
私人油漆;
私人涂料;
私有堆栈路径;
私有堆栈内存列表;
公共手势视图(上下文){
超级(上下文);
init();
}
公共手势视图(上下文、属性集属性){
超级(上下文,attrs);
init();
}
公共手势视图(上下文、属性集属性、int-defStyleAttr){
super(上下文、attrs、defStyleAttr);
init();
}
私有void init(){
setOnTouchListener(这个);
setBackgroundColor(颜色:白色);
linePaint=新油漆(油漆.防油漆别名标志);
linePaint.setStrokeWidth(默认LineStrokeWidth);
linePaint.setDither(真);
linePaint.setAntiAlias(真);
linePaint.setColor(颜色:黑色);
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeCap(油漆盖圆形);
linePaint.setStrokeJoin(绘制.连接.圆形);
linePaint.setPathEffect(新的CornerPathEffect(10));
rectPaint=新油漆(油漆.防油漆别名标志);
矩形油漆。设置行程宽度(0.5f);
rectPaint.setAntiAlias(true);
rectPaint.setColor(Color.RED);
rectPaint.setStyle(Paint.Style.STROKE);
路径=新堆栈();
memoryList=新堆栈();
}
公共void setPaintColor(@ColorInt-color){
默认颜色=颜色;
}
公共无效显示边界(布尔显示){
showBounds=show;
使无效();
}
公共void setDeleteMode(布尔删除模式){
this.isDeleteMode=deleteMode;
使无效();
}
公共void setLineStrokeWidth(整型宽度){
如果(宽度>0){
defaultLineStrokeWidth=宽度;
}否则{
Log.e(“GestureView”,“笔划宽度不能为零或更小”);
}
}
public void setLineAlpha(@IntRange(from=0,to=255)int alpha){
默认α=α;
}
public int getDefaultLineStrokeWidth(){
返回defaultLineStrokeWidth;
}
公共屏幕(){
currentPathIndex=0;
清除路径();
memoryList.clear();
使无效();
}
@凌驾
受保护的void onDraw(画布){
if(path.size()>0){
对于(int i=0;i