Сохранять пути холста к SharedPreference и перерисовывать на холсте при открытии приложения

У меня есть пользовательский вид, который я использовал для рисования разных размеров и изображения на холсте. Здорово. Поэтому каждый раз, когда я рисую что-то, я добавляю эту информацию в список действий.

Когда пользователь выходит из приложения, я сохраняю этот список действий как строку в sharedPreference. В то время, когда пользователь снова открывает приложение, я получаю эти данные и использую Gson, чтобы преобразовать его обратно в список previous_drawn_paths и обновить actionList с этим.

Когда я это делаю, я получаю ошибку сегментации, но есть ссылка на данные и память. Я также добавил код и ловушку с надгробным камнем.

DrawingView.java

public class DrawingView extends View { public enum Type { PATH, TEXT, STAMP; } /** * Different type of draw */ public enum Mode { DRAW, ERASER, TEXT, STAMP; } /** * Different Modes for Drawing */ public enum Drawer { PEN, LINE, ELLIPSE; } /** * Different Modes of Stamps */ public enum Stamper { STAR, THUMB; } private Context context = null; private Canvas canvas = null; private Bitmap bitmap = null; private int width; private int height; private int historyPointer = 0; private List<DrawingAction> previous_action_list = new ArrayList<>(); private String TAG = this.getClass().getCanonicalName(); public List<DrawingAction> getPrevious_action_list() { return previous_action_list; } public void setPrevious_action_list(List<DrawingAction> previous_action_list) { this.previous_action_list = previous_action_list; updateHistoryPath(); } /** * Collection of different types of actions */ private List<DrawingAction> actionLists = new ArrayList<>(); public List<DrawingAction> getActionLists() { return actionLists; } /** * Flags for maintaining the states */ private boolean enabled = false; private boolean isDown = false; private Mode mode = Mode.DRAW; private Drawer drawer = Drawer.PEN; private Stamper stamper = Stamper.STAR; private float startX = 0F; private float startY = 0F; private Paint drawPaint; private Paint erasePaint; private Paint textPaint; private Bitmap starPaint; private Bitmap thumbPaint; public DrawingView(Context context) { super(context); this.setup(context); } public DrawingView(Context context, AttributeSet attrs) { super(context, attrs); this.setup(context); } public DrawingView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.setup(context); } private void setup(Context context) { this.context = context; createDrawPaint(); createErasePaint(); createTextPaint(); createStamperPaint(context); } private void createDrawPaint() { this.drawPaint = new Paint(); this.drawPaint.setAntiAlias(true); this.drawPaint.setStyle(Paint.Style.STROKE); this.drawPaint.setStrokeWidth(10F); this.drawPaint.setStrokeCap(Paint.Cap.BUTT); this.drawPaint.setStrokeJoin(Paint.Join.MITER); this.drawPaint.setColor(Color.RED); this.drawPaint.setAlpha(255); } private void createErasePaint() { this.erasePaint = new Paint(); this.erasePaint.setColor(Color.WHITE); this.erasePaint.setAlpha(255); this.erasePaint.setAntiAlias(true); this.erasePaint.setDither(true); this.erasePaint.setStyle(Paint.Style.STROKE); this.erasePaint.setStrokeJoin(Paint.Join.ROUND); this.erasePaint.setStrokeCap(Paint.Cap.ROUND); this.erasePaint.setStrokeWidth(10F); } private void createTextPaint() { this.textPaint = new Paint(); this.textPaint.setAntiAlias(true); this.textPaint.setStyle(Paint.Style.STROKE); this.textPaint.setStrokeCap(Paint.Cap.BUTT); this.textPaint.setStrokeJoin(Paint.Join.MITER); this.textPaint.setTypeface(Typeface.DEFAULT); this.textPaint.setTextSize(56F); this.textPaint.setTextAlign(Paint.Align.RIGHT); this.drawPaint.setColor(Color.RED); this.textPaint.setStrokeWidth(0F); } private void createStamperPaint(Context context) { this.starPaint = BitmapFactory.decodeResource(context.getResources(), R.mipmap.stamp_star); this.thumbPaint = BitmapFactory.decodeResource(context.getResources(), R.mipmap.stamp_thumb); } private DrawingAction getCurrentAction() { return this.actionLists.get(this.historyPointer-1); } private void drawText(DrawingAction action, Canvas canvas) { String text = action.getText(); if((text == null) || (text.length() <= 0)) { return; } float textX = action.getPositionX(); float textY = action.getPositionY(); Paint paintMeasureText = new Paint(); float textLength = paintMeasureText.measureText(text); float lengthOfChar = textLength / (float) text.length(); float restWidth = this.canvas.getWidth() - textX; // text-align : right int numChars = (lengthOfChar <= 0) ? 1 : (int) Math.floor((double) (restWidth / lengthOfChar)); // The number of characters at 1 line int modNumChars = (numChars < 1) ? 1 : numChars; float y = textY; for (int i = 0, len = text.length(); i < len; i += modNumChars) { String substring = ""; if ((i + modNumChars) < len) { substring = text.substring(i, (i + modNumChars)); } else { substring = text.substring(i, len); } //TODO: Adjust according to the font size y += 56F; canvas.drawText(substring, textX, y, this.textPaint); } } private void updateHistory(DrawingAction action) { if (this.historyPointer == this.actionLists.size()) { this.actionLists.add(action); Log.d(TAG,"history pointer update"+this.historyPointer); this.historyPointer++; } else { // Removing the unused actions in history this.actionLists.set(this.historyPointer, action); this.historyPointer++; for (int i = this.historyPointer, size = this.actionLists.size(); i < size; i++) { this.actionLists.remove(this.historyPointer); } } } private void updateHistoryPath() { for(int index=0 ; index<previous_action_list.size(); index++) { Log.d(TAG,"adding canvas index from previous list"+index); if (previous_action_list.get(index).getType()!=null) { updateHistory(new DrawingAction(previous_action_list.get(index).getType(),previous_action_list.get(index).getPath(),previous_action_list.get(index).getPaint())); } } } public boolean undo() { if (this.historyPointer > 1) { this.historyPointer--; this.invalidate(); return true; } else { return false; } } public boolean redo() { if (this.historyPointer < this.actionLists.size()) { this.historyPointer++; this.invalidate(); return true; } else { return false; } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.TRANSPARENT); if (this.bitmap != null) { canvas.drawBitmap(this.bitmap, 0F, 0F, new Paint()); } // this.historyPointer for (int i = 0; i < this.historyPointer; i++) { DrawingAction action = this.actionLists.get(i); Type type = action.getType(); if(type == Type.PATH) { canvas.drawPath(action.getPath(), action.getPaint()); Log.d("lingaraj","on draw history index"+i); } else if(type == Type.TEXT) { this.drawText(action, canvas); } else if(type == Type.STAMP) { Stamper stamper = action.getStamper(); if(stamper == Stamper.STAR) { canvas.drawBitmap(this.starPaint, action.getPositionX(), action.getPositionY(), new Paint()); } else if(stamper == Stamper.THUMB) { canvas.drawBitmap(this.thumbPaint, action.getPositionX(), action.getPositionY(), new Paint()); } } } this.canvas = canvas; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); } public void setCustomWidth(int width) { this.width = width; } public int getCustomWidth() { return this.width; } public void setCustomHeight(int height) { this.height = height; } public int getCustomHeight() { return this.height; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public boolean getEnabled() { return this.enabled; } public void setMode(Mode mode) { this.mode = mode; } public Mode getMode() { return this.mode; } public void setDrawer(Drawer drawer) { this.drawer = drawer; this.mode = Mode.DRAW; } public void setStamper(Stamper stamper) { this.stamper = stamper; this.mode = Mode.STAMP; } public void setBitmap(Bitmap bitmap) { this.bitmap = bitmap; invalidate(); } } 

DrawingAction.java:

 public class DrawingAction { private DrawingView.Type type; private Path path; private Paint paint; private String text; private DrawingView.Stamper stamper; private float positionX; private float positionY; public DrawingAction(DrawingView.Type type, Path path, Paint paint) { this.type = type; this.path = path; this.paint = paint; } public DrawingAction(DrawingView.Type type, Path path, Paint paint, float positionX, float positionY) { this.type = type; this.path = path; this.paint = paint; this.positionX = positionX; this.positionY = positionY; } public DrawingAction(DrawingView.Type type, String text, float positionX, float positionY) { this.type = type; this.text = text; this.positionX = positionX; this.positionY = positionY; } public DrawingAction(DrawingView.Type type, DrawingView.Stamper stamper, float positionX, float positionY) { this.type = type; this.stamper = stamper; this.positionX = positionX; this.positionY = positionY; } public DrawingView.Type getType() { return type; } public Path getPath() { return path; } public void setPath(Path path) { this.path = path; } public Paint getPaint() { return paint; } public void setPaint(Paint paint) { this.paint = paint; } public String getText() { return text; } public void setText(String text) { this.text = text; } public DrawingView.Stamper getStamper() { return stamper; } public void setStamper(DrawingView.Stamper stamper) { this.stamper = stamper; } public float getPositionX() { return positionX; } public void setPositionX(float positionX) { this.positionX = positionX; } public float getPositionY() { return positionY; } public void setPositionY(float positionY) { this.positionY = positionY; } } 

MainActivity.java:

 public class MainActivity extends AppCompatActivity { public static final String TAG = "Draw"; private DrawingView drawing; private CanvasScroll scroll; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_correct); drawing = (DrawingView) findViewById(R.id.canvasDrawing); List<DrawingAction> drawing_action_list = new ArrayList<>(); drawing_action_list = stringToList(Settings.getCorrectionPath(getApplicationContext())); disableScroll(); if (drawing_action_list.isEmpty()) { Log.d(TAG,"Drawing action list empty previous path not drawn"); } else { drawing.setPrevious_action_list(drawing_action_list); Log.d(TAG,"Drawing action list previous path drawn on canvas"); } } 

LogCat:

 A/libc : Fatal signal 11 (SIGSEGV) at 0xb7bdb5a0 (code=1), thread 2064 (hourglass.drawing) 

Надгробная плита:

 backtrace: --------- log /dev/log/main 08-20 02:39:00.584 2064 2064 D dalvikvm: Not late-enabling CheckJNI (already on) 08-20 02:39:00.664 2064 2064 W dalvikvm: VFY: unable to find class referenced in signature (Landroid/view/SearchEvent;) 08-20 02:39:00.664 2064 2064 I dalvikvm: Could not find method android.view.Window$Callback.onSearchRequested, referenced from method android.support.v7.view.WindowCallbackWrapper.onSearchRequested 08-20 02:39:00.664 2064 2064 W dalvikvm: VFY: unable to resolve interface method 19785: Landroid/view/Window$Callback;.onSearchRequested (Landroid/view/SearchEvent;)Z 08-20 02:39:00.664 2064 2064 D dalvikvm: VFY: replacing opcode 0x72 at 0x0002 08-20 02:39:00.664 2064 2064 I dalvikvm: Could not find method android.view.Window$Callback.onWindowStartingActionMode, referenced from method android.support.v7.view.WindowCallbackWrapper.onWindowStartingActionMode 08-20 02:39:00.664 2064 2064 W dalvikvm: VFY: unable to resolve interface method 19789: Landroid/view/Window$Callback;.onWindowStartingActionMode (Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode; 08-20 02:39:00.664 2064 2064 D dalvikvm: VFY: replacing opcode 0x72 at 0x0002 08-20 02:39:00.684 2064 2064 I dalvikvm: Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.widget.TintTypedArray.getChangingConfigurations 08-20 02:39:00.684 2064 2064 W dalvikvm: VFY: unable to resolve virtual method 448: Landroid/content/res/TypedArray;.getChangingConfigurations ()I 08-20 02:39:00.684 2064 2064 D dalvikvm: VFY: replacing opcode 0x6e at 0x0002 08-20 02:39:00.684 2064 2064 I dalvikvm: Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.widget.TintTypedArray.getType 08-20 02:39:00.694 2064 2064 W dalvikvm: VFY: unable to resolve virtual method 470: Landroid/content/res/TypedArray;.getType (I)I 08-20 02:39:00.694 2064 2064 D dalvikvm: VFY: replacing opcode 0x6e at 0x0002 08-20 02:39:00.734 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 240K, 9% free 3098K/3400K, paused 39ms, total 41ms 08-20 02:39:00.884 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 9K, 9% free 3121K/3400K, paused 3ms, total 3ms 08-20 02:39:00.934 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 65.356MB for 65280012-byte allocation 08-20 02:39:00.954 2064 2072 D dalvikvm: GC_FOR_ALLOC freed <1K, 1% free 66870K/67152K, paused 16ms, total 16ms 08-20 02:39:01.254 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 46K, 1% free 66909K/67164K, paused 4ms, total 5ms 08-20 02:39:01.264 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 75.718MB for 10825612-byte allocation 08-20 02:39:01.284 2064 2072 D dalvikvm: GC_FOR_ALLOC freed 2K, 1% free 77479K/77736K, paused 17ms, total 17ms 08-20 02:39:01.314 2064 2064 Din.co.hourglass.drawing.MainActivity: Original pixels3400/796 08-20 02:39:01.324 2064 2064 Din.co.hourglass.drawing.MainActivity: Scaled pixels1700/398 08-20 02:39:01.324 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 1K, 1% free 77478K/77736K, paused 3ms, total 3ms 08-20 02:39:01.324 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 78.296MB for 2706412-byte allocation 08-20 02:39:01.344 2064 2072 D dalvikvm: GC_FOR_ALLOC freed <1K, 1% free 80121K/80380K, paused 15ms, total 15ms 08-20 02:39:01.374 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 10572K, 14% free 69550K/80380K, paused 3ms, total 3ms 08-20 02:39:01.374 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 78.738MB for 11288012-byte allocation 08-20 02:39:01.424 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 12% free 80573K/91404K, paused 2ms, total 2ms 08-20 02:39:01.424 2064 2064 Din.co.hourglass.drawing.MainActivity: Original pixels3400/830 08-20 02:39:01.424 2064 2064 Din.co.hourglass.drawing.MainActivity: Scaled pixels1700/415 08-20 02:39:01.424 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 12% free 80573K/91404K, paused 3ms, total 3ms 08-20 02:39:01.434 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 81.429MB for 2822012-byte allocation 08-20 02:39:01.434 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 9% free 83329K/91404K, paused 3ms, total 3ms 08-20 02:39:01.434 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 9% free 83329K/91404K, paused 2ms, total 3ms 08-20 02:39:01.434 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 86.701MB for 5528412-byte allocation 08-20 02:39:01.444 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 3% free 88728K/91404K, paused 2ms, total 2ms 08-20 02:39:01.484 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 16422K, 4% free 72306K/75312K, paused 4ms, total 4ms 08-20 02:39:01.484 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 81.221MB for 11070412-byte allocation 08-20 02:39:01.534 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 4% free 83117K/86124K, paused 10ms, total 10ms 08-20 02:39:01.534 2064 2064 Din.co.hourglass.drawing.MainActivity: Original pixels3400/814 08-20 02:39:01.534 2064 2064 Din.co.hourglass.drawing.MainActivity: Scaled pixels1700/407 08-20 02:39:01.544 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 4% free 83117K/86124K, paused 8ms, total 8ms 08-20 02:39:01.544 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 83.861MB for 2767612-byte allocation 08-20 02:39:01.554 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 1% free 85819K/86124K, paused 12ms, total 12ms 08-20 02:39:01.564 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 10811K, 1% free 75008K/75312K, paused 2ms, total 3ms 08-20 02:39:01.564 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 81.215MB for 8296012-byte allocation 08-20 02:39:01.574 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 1% free 83110K/83416K, paused 5ms, total 6ms 08-20 02:39:01.594 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 8101K, 11% free 75009K/83416K, paused 4ms, total 4ms 08-20 02:39:01.594 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 77.350MB for 4243212-byte allocation 08-20 02:39:01.614 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 6% free 79152K/83416K, paused 2ms, total 2ms 08-20 02:39:01.614 2064 2064 Din.co.hourglass.drawing.MainActivity: Original pixels3400/312 08-20 02:39:01.614 2064 2064 Din.co.hourglass.drawing.MainActivity: Scaled pixels1700/156 08-20 02:39:01.614 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 4144K, 9% free 76045K/83416K, paused 2ms, total 3ms 08-20 02:39:01.614 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 83.239MB for 9356812-byte allocation 08-20 02:39:01.624 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 8% free 85182K/92556K, paused 2ms, total 3ms 08-20 02:39:01.624 2064 2064 Din.co.hourglass.drawing.MainActivity: Bitmap Merged 08-20 02:39:01.714 2064 2064 D : HostConnection::get() New Host Connection established 0xb833f3c0, tid 2064 08-20 02:39:02.844 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 18381K, 8% free 67150K/72492K, paused 3ms, total 8ms 08-20 02:39:02.844 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 77.371MB for 12312340-byte allocation 08-20 02:39:02.884 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 8K, 7% free 79165K/84516K, paused 3ms, total 3ms 08-20 02:39:02.904 2064 2064 D lingaraj: adding canvas index from previous list0 08-20 02:39:02.904 2064 2064 D lingaraj: history pointer update0 08-20 02:39:02.904 2064 2064 D lingaraj: adding canvas index from previous list1 08-20 02:39:02.904 2064 2064 D lingaraj: history pointer update1 08-20 02:39:02.914 2064 2064 D Drawing: Drawing action list previous path drawn on canvas 08-20 02:39:03.074 2064 2064 D dalvikvm: GC_FOR_ALLOC freed 337K, 7% free 79264K/84516K, paused 3ms, total 4ms 08-20 02:39:03.074 2064 2064 I dalvikvm-heap: Grow heap (frag case) to 86.820MB for 9815116-byte allocation 08-20 02:39:03.084 2064 2064 D dalvikvm: GC_FOR_ALLOC freed <1K, 6% free 88849K/94104K, paused 2ms, total 3ms 08-20 02:39:03.084 2064 2064 F libc : Fatal signal 11 (SIGSEGV) at 0xb7bdb5a0 (code=1), thread 2064 (hourglass.drawing) 

Проблема в преобразовании и сохранении объектов, таких как краска и т. Д. У меня есть альтернативное решение для того, чего вы хотите достичь: – вы хотите, чтобы следующий список данных сохранялся в предпочтении:

  private DrawingView.Type type; private Path path; private Paint paint; private String text; private DrawingView.Stamper stamper; private float positionX; private float positionY; 

Вместо этого вы можете использовать примитивные данные и реализовывать их. Я имею в виду, что вам не нужно писать весь объект рисования, но значения, которые вы устанавливаете в объекте paint, т.е. некоторые примитивные значения. (Аналогично проверять тип и тип)

На основе сообщений logcat, подобных этому:

… 2064 2064 I dalvikvm-heap: разрастайте кучу (фрагмент) до 65.356MB для 65280012-байтового распределения

Вы выделяете много памяти, возможно, для некоторых растровых изображений, которые слишком велики для устройства. Например, 65MB может хранить растровое изображение 4000×4000 пикселей.

Попробуйте отключить часть вашего приложения, которое загружает эти ресурсы, или замените их чем-то оптимизированным для размера дисплея.

Следующее – это рабочее решение для сохранения путей и повторной перерисовки, вместо того, чтобы накладывать его на изображение и сохранять. В моем случае сохраненный путь – это проблема не объекта рисования, который я сохраняю.

PathPoint.Java

Я сохраняю координаты каждого действия, которое было сделано пользователем для этого объекта, и добавьте его в список в DrawingAction.java

 public class PathPoint { float startX; float startY; public float getStartX() { return startX; } public void setStartX(float startX) { this.startX = startX; } public float getStartY() { return startY; } public void setStartY(float startY) { this.startY = startY; } } 

DrawingAction.java

Добавлен следующий фрагмент кода DrawingAction.java

  private List<PathPoint> pts = new ArrayList<>(); public CorrectionView.Drawer getDrawer() { return drawer; } public List<PathPoint> getPts() { return pts; } public void setPts(List<PathPoint> pts) { this.pts = pts; } public void addPts(PathPoint point) { this.pts.add(point); //Adds touch co-ordinates to this list from Drawing View( on Touch Listener) } 

DrawingView.java

Таким образом, в моем DrawingView, когда данные искажаются из json, я создаю новый путь и рисую с использованием co_ordinates (PathPoint) из каждого действия. Таким образом, я смог добиться рисования с сохраненных путей.

  public void setPrevious_action_list(List<DrawingAction> previous_action_list) { // updateActionListPath(previous_action_list); this.previous_action_list = previous_action_list; Path drawing_path; for (DrawingAction action:previous_action_list) { drawing_path = new Path(); if (action.getType().equals(Type.PATH) && action.getDrawer().equals(Drawer.PEN) && action.getPts().size()>0) { //Setting starting path to path_point(0).startx and starty, if not set the points will be started from top corner. drawing_path.moveTo(action.getPts().get(0).getStartX(),action.getPts().get(0).getStartY()); drawing_path.lineTo(action.getPts().get(0).getStartX(),action.getPts().get(0).getStartY()); drawing_path.moveTo(action.getPts().get(action.getPts(0).getStartX(),action.getPts().get(action.getPts(0).getStartY()); for (PathPoint path_point:action.getPts()) { drawing_path.lineTo(path_point.getStartX(),path_point.getStartY()); } action.setPath(drawing_path); action.setPaint(this.drawPaint); } else if (action.getType().equals(Type.PATH) && action.getDrawer().equals(Drawer.LINE) && action.getPts().size()>0) { Log.d(TAG,"Using Line in setting action path"); drawing_path = new Path(); drawing_path.moveTo(action.getPts().get(0).getStartX(),action.getPts().get(0).getStartY()); for (PathPoint path_point:action.getPts()) { drawing_path.lineTo(path_point.getStartX(),path_point.getStartY()); } action.setPath(drawing_path); action.setPaint(this.drawPaint); } else if (action.getType().equals(Type.PATH) && action.getDrawer().equals(Drawer.ELLIPSE) && action.getPts().size()>0) { if (action.getPts().size()==2) { drawing_path = new Path(); float start_x = action.getPts().get(0).getStartX(); float start_y = action.getPts().get(0).getStartY(); float end_x = action.getPts().get(1).getStartX(); float end_y = action.getPts().get(1).getStartY(); RectF rect = new RectF(start_x, start_y, end_x, end_y); drawing_path.reset(); drawing_path.addOval(rect, Path.Direction.CCW); action.setPath(drawing_path); action.setPaint(this.drawPaint); } } } updateHistoryPath(); invalidate(); } private void onActionMove(MotionEvent event) { if (!isDown) { return; } float x = event.getX(); float y = event.getY(); switch (this.mode) { case DRAW: DrawingAction drawing = this.getCurrentAction(); if(drawing.getType() == Type.PATH) { Path path = drawing.getPath(); switch (this.drawer) { case PEN: path.lineTo(x, y); PathPoint path_point = new PathPoint(); path_point.setStartX(x); path_point.setStartY(y); drawing.addPts(path_point); drawing.setPath(path); break; case LINE: path.reset(); path.moveTo(this.startX, this.startY); path.lineTo(x, y); // path_point = new PathPoint(); // path_point.setStartX(this.startX); // path_point.setStartY(this.startY); // drawing.addPts(path_point); path_point = new PathPoint(); path_point.setStartX(x); path_point.setStartY(y); drawing.addPts(path_point); drawing.setPath(path); break; case ELLIPSE: RectF rect = new RectF(this.startX, this.startY, x, y); path.reset(); path.addOval(rect, Path.Direction.CCW); path_point =new PathPoint(); path_point.setStartY(this.startX); path_point.setStartY(this.startY); drawing.addPts(path_point); path_point = new PathPoint(); path_point.setStartX(x); path_point.setStartY(y); drawing.addPts(path_point); drawing.setPath(path); break; } }