Tutorial Android DrawableView

Tutorial Android DrawableView
Pada artikel ini, kita mengimplementasikan DrawableView. Kita akan menerapkan warna seperti pada laptop kita. Mari kita lihat implementasi dari fungsi ini. Di bawah ini adalah contoh video untuk memberi Anda gambaran tentang apa yang akan kita lakukan di artikel ini. Harap dicatat bahwa kita akan mengimplementasikan proyek ini menggunakan bahasa program Java.

Fitur yang tersedia
Menambahkan lebar Stroke
Mengurangi lebar Stroke
Mengubah warna goresan
Membatalkan lukisan


Langkah demi langkah lengkap untuk membantu Anda mempelajari cara menggambar DrawableView dari awal. Kita mulai dengan dasar-dasarnya, yang mencakup semuanya mulai dari atribut yang akan Anda gunakan hingga tata letak XML yang akan Anda gunakan untuk menampilkan DrawableView ke dalam aplikasi Android Anda sendiri.
Buka Aplikasi > res/layout/activity_main.xml dan tambahkan kode berikut ke file ini. Di bawah ini adalah kode untuk file activity_main.xml.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="match_parent"
	android:layout_height="match_parent">
<LinearLayout
	android:layout_width="match_parent"
	android:layout_height="wrap_content"
	android:gravity="center">
<Button
	android:id="@+id/strokeWidthPlusButton"
	android:text="SW+"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"/>
<Button
	android:id="@+id/strokeWidthMinusButton"
	android:text="SW-"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"/>
<Button
		android:id="@+id/changeColorButton"
		android:text="Color"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"/>
		<Button
			android:id="@+id/undoButton"
			android:text="Undo"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"/>
	</LinearLayout>
	<com.happycodx.app.DrawableView
		android:id="@+id/paintView"
		android:layout_width="match_parent"
		android:layout_height="match_parent"/>
</LinearLayout>

Buka file MainActivity.java dan lihat kode berikut. Di bawah ini adalah kode untuk file MainActivity.java. Komentar ditambahkan ke kode untuk pemahaman kode yang lebih baik.


package com.happycodx.app;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.util.Random;

public class MainActivity extends Activity {
	private DrawableView drawableView;
	private DvConfig config = new DvConfig();
	@Override protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initUi();
	}
	private void initUi() {
		drawableView = (DrawableView) findViewById(R.id.paintView);
		Button strokeWidthMinusButton = (Button) findViewById(R.id.strokeWidthMinusButton);
		Button strokeWidthPlusButton = (Button) findViewById(R.id.strokeWidthPlusButton);
		Button changeColorButton = (Button) findViewById(R.id.changeColorButton);
		Button undoButton = (Button) findViewById(R.id.undoButton);
		config.setStrokeColor(getResources().getColor(android.R.color.black));
		config.setShowCanvasBounds(true);
		config.setStrokeWidth(20.0f);
		config.setMinZoom(1.0f);
		config.setMaxZoom(3.0f);
		config.setCanvasHeight(1080);
		config.setCanvasWidth(1920);
		drawableView.setConfig(config);
		strokeWidthPlusButton.setOnClickListener(new View.OnClickListener() {

				@Override public void onClick(View v) {
					config.setStrokeWidth(config.getStrokeWidth() + 10);
				}
			});
		strokeWidthMinusButton.setOnClickListener(new View.OnClickListener() {

				@Override public void onClick(View v) {
					config.setStrokeWidth(config.getStrokeWidth() - 10);
				}
			});
		changeColorButton.setOnClickListener(new View.OnClickListener() {

				@Override public void onClick(View v) {
					Random random = new Random();
					config.setStrokeColor(
						Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256)));
				}
			});
		undoButton.setOnClickListener(new View.OnClickListener() {

				@Override public void onClick(View v) {
					drawableView.undo();
				}
			});
	}
}

Buat sebuah file untuk Canvas drawer sebagai CvDrawee.java


package com.happycodx.app;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;

public class CvDrawee {

	private boolean showCanvasBounds;
	private Paint paint;
	private float scaleFactor = 1.0f;
	private RectF viewRect = new RectF();
	private RectF canvasRect = new RectF();
	private CvLogr canvasLogger;

	public CvDrawee() {
		initPaint();
		initLogger();
	}

	public void onDraw(Canvas canvas) {
		canvasLogger.log(canvas, canvasRect, viewRect, scaleFactor);
		if (showCanvasBounds) {
			canvas.drawRect(canvasRect, paint);
		}
		canvas.translate(-viewRect.left, -viewRect.top);
		canvas.scale(scaleFactor, scaleFactor);
	}

	public void onScaleChange(float scaleFactor) {
		this.scaleFactor = scaleFactor;
	}

	public void onViewPortChange(RectF viewRect) {
		this.viewRect = viewRect;
	}

	public void onCanvasChanged(RectF canvasRect) {
		this.canvasRect = canvasRect;
	}

	private void initPaint() {
		paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
		paint.setStrokeWidth(2.0f);
		paint.setStyle(Paint.Style.STROKE);
	}

	private void initLogger() {
		if (BuildConfig.DEBUG) {
			canvasLogger = new DebugCvLogr();
		} else {
			canvasLogger = new NullCvLogr();
		}
	}

	public void setConfig(DvConfig config) {
		this.showCanvasBounds = config.isShowCanvasBounds();
	}
}


Buat sebuah file untuk pencatat Canvas sebagai CvLogr.java


package com.happycodx.app;

import android.graphics.Canvas;
import android.graphics.RectF;

public interface CvLogr {
	void log(Canvas canvas, RectF canvasRect, RectF viewRect, float scaleFactor);
}


Buat sebuah file untuk Debug pencatat Canvas sebagai DebugCvLogr.java


package com.happycodx.app;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;

public class DebugCvLogr implements CvLogr {

	private Paint paint;

	public DebugCvLogr() {
		paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
		paint.setTextSize(25.0f);
	}

	public void log(Canvas canvas, RectF canvasRect, RectF viewRect, float scaleFactor) {
		if (BuildConfig.DEBUG) {
			RectF notScaled = new RectF(canvasRect);
			notScaled.right /= scaleFactor;
			notScaled.bottom /= scaleFactor;
			int lineNumber = 0;
			logLine(canvas, "Canvas: " + toShortString(canvasRect), ++lineNumber);
			logLine(canvas, "No scaled canvas: " + toShortString(notScaled), ++lineNumber);
			logLine(canvas, "View: " + toShortString(viewRect), ++lineNumber);
			logLine(canvas, "Scale factor: " + scaleFactor + "x", ++lineNumber);
		}
	}

	private static String toShortString(RectF rectf) {
		return "["
			+ rectf.left
			+ ','
			+ rectf.top
			+ "]["
			+ rectf.right
			+ ','
			+ rectf.bottom
			+ "] B["
			+ rectf.width()
			+ ","
			+ rectf.height()
			+ "]";
	}

	private void logLine(Canvas canvas, String text, int lineNumber) {
		canvas.drawText(text, 5, 30 * lineNumber, paint);
	}
}


Buat sebuah file untuk tampilan DrawableView sebagai DrawableView.java


package com.happycodx.app;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.os.Build;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import java.util.ArrayList;

public class DrawableView extends View
implements View.OnTouchListener, ScrollrListener, GestureCrtListener, ScalrListenee {

	private final ArrayList paths = new ArrayList<>();

	private GestureScroll gestureScroller;
	private GestureScler gestureScaler;
	private GestureCrt gestureCreator;
	private int canvasHeight;
	private int canvasWidth;
	private GestureDetector gestureDetector;
	private ScaleGestureDetector scaleGestureDetector;
	private PtDrawer pathDrawer;
	private CvDrawee canvasDrawer;
	private SerialPt currentDrawingPath;

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

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

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

	@TargetApi(Build.VERSION_CODES.LOLLIPOP) public DrawableView(Context context, AttributeSet attrs,
																 int defStyleAttr, int defStyleRes) {
		super(context, attrs, defStyleAttr, defStyleRes);
		init();
	}

	private void init() {
		gestureScroller = new GestureScroll(this);
		gestureDetector = new GestureDetector(getContext(), new GestureScrListener(gestureScroller));
		gestureScaler = new GestureScler(this);
		scaleGestureDetector =
			new ScaleGestureDetector(getContext(), new GestureSclListener(gestureScaler));
		gestureCreator = new GestureCrt(this);
		pathDrawer = new PtDrawer();
		canvasDrawer = new CvDrawee();
		setOnTouchListener(this);
	}

	public void setConfig(DvConfig config) {
		if (config == null) {
			throw new IllegalArgumentException("Paint configuration cannot be null");
		}
		canvasWidth = config.getCanvasWidth();
		canvasHeight = config.getCanvasHeight();
		gestureCreator.setConfig(config);
		gestureScaler.setZooms(config.getMinZoom(), config.getMaxZoom());
		gestureScroller.setCanvasBounds(canvasWidth, canvasHeight);
		canvasDrawer.setConfig(config);
	}

	@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		gestureScroller.setViewBounds(w, h);
	}

	@Override public boolean onTouch(View v, MotionEvent event) {
		scaleGestureDetector.onTouchEvent(event);
		gestureDetector.onTouchEvent(event);
		gestureCreator.onTouchEvent(event);
		invalidate();
		return true;
	}

	public void undo() {
		if (paths.size() > 0) {
			paths.remove(paths.size() - 1);
			invalidate();
		}
	}

	@Override protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvasDrawer.onDraw(canvas);
		pathDrawer.onDraw(canvas, currentDrawingPath, paths);
	}

	public void clear() {
		paths.clear();
		invalidate();
	}

	public Bitmap obtainBitmap(Bitmap createdBitmap) {
		return pathDrawer.obtainBitmap(createdBitmap, paths);
	}

	public Bitmap obtainBitmap() {
		return obtainBitmap(Bitmap.createBitmap(canvasWidth, canvasHeight, Bitmap.Config.ARGB_8888));
	}

	@Override protected Parcelable onSaveInstanceState() {
		DvSaveStat state = new DvSaveStat(super.onSaveInstanceState());
		state.setPaths(paths);
		return state;
	}

	@Override protected void onRestoreInstanceState(Parcelable state) {
		if (!(state instanceof DvSaveStat)) {
			super.onRestoreInstanceState(state);
		} else {
			DvSaveStat ss = (DvSaveStat) state;
			super.onRestoreInstanceState(ss.getSuperState());
			paths.addAll(ss.getPaths());
		}
	}

	@Override public void onViewPortChange(RectF currentViewport) {
		gestureCreator.onViewPortChange(currentViewport);
		canvasDrawer.onViewPortChange(currentViewport);
	}

	@Override public void onCanvasChanged(RectF canvasRect) {
		gestureCreator.onCanvasChanged(canvasRect);
		canvasDrawer.onCanvasChanged(canvasRect);
	}

	@Override public void onGestureCreated(SerialPt serializablePath) {
		paths.add(serializablePath);
	}

	@Override public void onCurrentGestureChanged(SerialPt currentDrawingPath) {
		this.currentDrawingPath = currentDrawingPath;
	}

	@Override public void onScaleChange(float scaleFactor) {
		gestureScroller.onScaleChange(scaleFactor);
		gestureCreator.onScaleChange(scaleFactor);
		canvasDrawer.onScaleChange(scaleFactor);
	}
}


Buat sebuah file untuk Konfigurasi tampilan drawable sebagai DvConfig.java


package com.happycodx.app;

import java.io.Serializable;

public class DvConfig implements Serializable {

	private float strokeWidth;
	private int strokeColor;
	private int canvasWidth;
	private int canvasHeight;
	private float minZoom;
	private float maxZoom;
	private boolean showCanvasBounds;

	public float getMaxZoom() {
		return maxZoom;
	}

	public void setMaxZoom(float maxZoom) {
		this.maxZoom = maxZoom;
	}

	public float getMinZoom() {
		return minZoom;
	}

	public void setMinZoom(float minZoom) {
		this.minZoom = minZoom;
	}

	public int getCanvasHeight() {
		return canvasHeight;
	}

	public void setCanvasHeight(int canvasHeight) {
		this.canvasHeight = canvasHeight;
	}

	public int getCanvasWidth() {
		return canvasWidth;
	}

	public void setCanvasWidth(int canvasWidth) {
		this.canvasWidth = canvasWidth;
	}

	public float getStrokeWidth() {
		return strokeWidth;
	}

	public void setStrokeWidth(float strokeWidth) {
		this.strokeWidth = strokeWidth;
	}

	public int getStrokeColor() {
		return strokeColor;
	}

	public void setStrokeColor(int strokeColor) {
		this.strokeColor = strokeColor;
	}

	public boolean isShowCanvasBounds() {
		return showCanvasBounds;
	}

	public void setShowCanvasBounds(boolean showCanvasBounds) {
		this.showCanvasBounds = showCanvasBounds;
	}
}


Buat sebuah file untuk Status penyimpanan tampilan drawable sebagai DvSaveStat.java


package com.happycodx.app;

import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;
import java.util.ArrayList;

public class DvSaveStat extends View.BaseSavedState {

	private ArrayList paths;

	public DvSaveStat(Parcel in) {
		super(in);
		this.paths = (ArrayList) in.readSerializable();
		for (SerialPt p : paths) {
			p.loadPathPointsAsQuadTo();
		}
	}

	public DvSaveStat(Parcelable parcelable) {
		super(parcelable);
	}

	@Override public void writeToParcel(Parcel dest, int flags) {
		dest.writeSerializable(this.paths);
	}

	public ArrayList getPaths() {
		return paths;
	}

	public void setPaths(ArrayList paths) {
		this.paths = paths;
	}

	public static final Creator CREATOR =
	new Creator() {
        public DvSaveStat createFromParcel(Parcel source) {
			return new DvSaveStat(source);
        }

        public DvSaveStat[] newArray(int size) {
			return new DvSaveStat[size];
        }
	};
}


Buat sebuah file untuk gerakan sebagai GestureCrt.java


package com.happycodx.app;

import android.graphics.RectF;
import android.support.v4.view.MotionEventCompat;
import android.view.MotionEvent;

public class GestureCrt {

	private SerialPt currentDrawingPath = new SerialPt();
	private GestureCrtListener delegate;
	private DvConfig config;
	private boolean downAndUpGesture = false;
	private float scaleFactor = 1.0f;
	private RectF viewRect = new RectF();
	private RectF canvasRect = new RectF();

	public GestureCrt(GestureCrtListener delegate) {
		this.delegate = delegate;
	}

	public void onTouchEvent(MotionEvent event) {
		float touchX = (MotionEventCompat.getX(event, 0) + viewRect.left) / scaleFactor;
		float touchY = (MotionEventCompat.getY(event, 0) + viewRect.top) / scaleFactor;

		//Log.d("Drawer", "T[" + touchX + "," + touchY + "] V[" + viewRect.toShortString() + "] S[" + scaleFactor + "]");
		switch (MotionEventCompat.getActionMasked(event)) {
			case MotionEvent.ACTION_DOWN:
				actionDown(touchX, touchY);
				break;
			case MotionEvent.ACTION_MOVE:
				actionMove(touchX, touchY);
				break;
			case MotionEvent.ACTION_UP:
				actionUp();
				break;
			case MotionEventCompat.ACTION_POINTER_DOWN:
				actionPointerDown();
				break;
		}
	}

	private void actionDown(float touchX, float touchY) {
		if (insideCanvas(touchX, touchY)) {
			downAndUpGesture = true;
			currentDrawingPath = new SerialPt();
			if (config != null) {
				currentDrawingPath.setColor(config.getStrokeColor());
				currentDrawingPath.setWidth(config.getStrokeWidth());
			}
			currentDrawingPath.saveMoveTo(touchX, touchY);
			delegate.onCurrentGestureChanged(currentDrawingPath);
		}
	}

	private void actionMove(float touchX, float touchY) {
		if (insideCanvas(touchX, touchY)) {
			downAndUpGesture = false;
			if (currentDrawingPath != null) {
				currentDrawingPath.saveLineTo(touchX, touchY);
			}
		} else {
			actionUp();
		}
	}

	private void actionUp() {
		if (currentDrawingPath != null) {
			if (downAndUpGesture) {
				currentDrawingPath.savePoint();
				downAndUpGesture = false;
			}
			delegate.onGestureCreated(currentDrawingPath);
			currentDrawingPath = null;
			delegate.onCurrentGestureChanged(null);
		}
	}

	private void actionPointerDown() {
		currentDrawingPath = null;
		delegate.onCurrentGestureChanged(null);
	}

	private boolean insideCanvas(float touchX, float touchY) {
		return canvasRect.contains(touchX, touchY);
	}

	public void setConfig(DvConfig config) {
		this.config = config;
	}

	public void onScaleChange(float scaleFactor) {
		this.scaleFactor = scaleFactor;
	}

	public void onViewPortChange(RectF viewRect) {
		this.viewRect = viewRect;
	}

	public void onCanvasChanged(RectF canvasRect) {
		this.canvasRect.right = canvasRect.right / scaleFactor;
		this.canvasRect.bottom = canvasRect.bottom / scaleFactor;
	}
}


Buat sebuah file untuk gerakan listener sebagai GestureCrtListener.java


package com.happycodx.app;

public interface GestureCrtListener {
	void onGestureCreated(SerialPt serializablePath);

	void onCurrentGestureChanged(SerialPt currentDrawingPath);
}


Buat sebuah file untuk Penskalaan gerakan sebagai GestureScler.java


package com.happycodx.app;

public class GestureScler implements GestureSclListener.OnScaleListener {

	private final ScalrListenee delegate;
	private float scaleFactor = 1.0f;
	private float minZoom;
	private float maxZoom;

	public GestureScler(ScalrListenee delegate) {
		this.delegate = delegate;
	}

	public void setZooms(float minZoom, float maxZoom) {
		this.minZoom = minZoom;
		this.maxZoom = maxZoom;
	}

	@Override public boolean onScale(float deltaScale) {
		scaleFactor *= deltaScale;
		scaleFactor = Math.max(minZoom, Math.min(scaleFactor, maxZoom));
		delegate.onScaleChange(scaleFactor);
		return true;
	}
}


Buat sebuah file untuk listener Penskalaan gerakan sebagai GestureSclListener.java


package com.happycodx.app;

import android.view.ScaleGestureDetector;

public final class GestureSclListener implements ScaleGestureDetector.OnScaleGestureListener {

	private OnScaleListener listener;

	public GestureSclListener(OnScaleListener listener) {
		this.listener = listener;
	}

	@Override public boolean onScale(ScaleGestureDetector detector) {
		return listener.onScale(detector.getScaleFactor());
	}

	@Override public boolean onScaleBegin(ScaleGestureDetector detector) {
		return true;
	}

	@Override public void onScaleEnd(ScaleGestureDetector detector) {
	}

	static interface OnScaleListener {
		boolean onScale(float scaleFactor);
	}
}


Buat sebuah file sebagai GestureScrListener.java


package com.happycodx.app;

import android.view.GestureDetector;
import android.view.MotionEvent;

public final class GestureScrListener implements GestureDetector.OnGestureListener {

  private OnGestureScrollListener listener;

  public GestureScrListener(OnGestureScrollListener listener) {
    this.listener = listener;
  }

  @Override public boolean onDown(MotionEvent e) {
    return true;
  }

  @Override public void onShowPress(MotionEvent e) {
  }

  @Override public boolean onSingleTapUp(MotionEvent e) {
    return false;
  }

  @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
      float distanceY) {
    return listener.onScroll(e1, e2, distanceX, distanceY);
  }

  @Override public void onLongPress(MotionEvent e) {
  }

  @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
      float velocityY) {
    return false;
  }

  static interface OnGestureScrollListener {
    boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
  }
}


Buat sebuah file gerakan gulir sebagai GestureScroll.java


package com.happycodx.app;

import android.graphics.RectF;
import android.support.v4.view.MotionEventCompat;
import android.view.MotionEvent;

public class GestureScroll implements GestureScrListener.OnGestureScrollListener {

	private final ScrollrListener listener;

	private float canvasWidth;
	private float canvasHeight;

	private RectF viewRect = new RectF();
	private RectF canvasRect = new RectF();

	public GestureScroll(final ScrollrListener listener) {
		this.listener = listener;
	}

	@Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
									  float distanceY) {
		if (hasTwoFingers(e2)) {
			float y = viewRect.bottom + distanceY;
			float x = viewRect.left + distanceX;
			setViewportBottomLeft(x, y);
		}
		return true;
	}

	public void setCanvasBounds(int canvasWidth, int canvasHeight) {
		this.canvasWidth = canvasWidth;
		canvasRect.right = canvasWidth;
		this.canvasHeight = canvasHeight;
		canvasRect.bottom = canvasHeight;
		listener.onCanvasChanged(canvasRect);
	}

	public void setViewBounds(int viewWidth, int viewHeight) {
		viewRect.right = viewWidth;
		viewRect.bottom = viewHeight;
		listener.onViewPortChange(viewRect);
	}

	public void onScaleChange(float scaleFactor) {
		canvasRect.right = canvasWidth * scaleFactor;
		canvasRect.bottom = canvasHeight * scaleFactor;
		listener.onCanvasChanged(canvasRect);
	}

	private void setViewportBottomLeft(float x, float y) {
		float viewWidth = viewRect.width();
		float viewHeight = viewRect.height();
		float left = Math.max(0, Math.min(x, canvasRect.width() - viewWidth));
		float bottom = Math.max(0 + viewHeight, Math.min(y, canvasRect.height()));
		float top = bottom - viewHeight;
		float right = left + viewWidth;
		viewRect.set(left, top, right, bottom);
		listener.onViewPortChange(viewRect);
	}

	private boolean hasTwoFingers(MotionEvent e) {
		return MotionEventCompat.getPointerCount(e) == 2;
	}
}


Buat sebuah file Pencatat kanvas nol sebagai NullCvLogr.java


package com.happycodx.app;

import android.graphics.Canvas;
import android.graphics.RectF;

public class NullCvLogr implements CvLogr {
	@Override public void log(Canvas canvas, RectF canvasRect, RectF viewRect, float scaleFactor) {
	}
}


Buat sebuah file jalur drawer sebagai PtDrawer.java


package com.happycodx.app;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import java.util.List;

public class PtDrawer {

	private Paint gesturePaint;

	public PtDrawer() {
		initGesturePaint();
	}

	public void onDraw(Canvas canvas, SerialPt currentDrawingPath, List paths) {
		drawGestures(canvas, paths);
		if (currentDrawingPath != null) {
			drawGesture(canvas, currentDrawingPath);
		}
	}

	public void drawGestures(Canvas canvas, List paths) {
		for (SerialPt path : paths) {
			drawGesture(canvas, path);
		}
	}

	public Bitmap obtainBitmap(Bitmap createdBitmap, List paths) {
		Canvas composeCanvas = new Canvas(createdBitmap);
		drawGestures(composeCanvas, paths);
		return createdBitmap;
	}

	private void drawGesture(Canvas canvas, SerialPt path) {
		gesturePaint.setStrokeWidth(path.getWidth());
		gesturePaint.setColor(path.getColor());
		canvas.drawPath(path, gesturePaint);
	}

	private void initGesturePaint() {
		gesturePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
		gesturePaint.setStyle(Paint.Style.STROKE);
		gesturePaint.setStrokeJoin(Paint.Join.ROUND);
		gesturePaint.setStrokeCap(Paint.Cap.ROUND);
	}
}


Buat sebuah file untuk penskalaan listener sebagai ScalrListenee.java


package com.happycodx.app;

public interface ScalrListenee {
  void onScaleChange(float scaleFactor);
}


Buat sebuah file untuk scroll listener sebagai ScrollrListener.java


package com.happycodx.app;

import android.graphics.RectF;

public interface ScrollrListener {
	void onViewPortChange(RectF currentViewport);
	void onCanvasChanged(RectF canvasRect);
}


Dan yang terakhir Buat sebuah file untuk Jalur serialisasi sebagai SerialPt.java


package com.happycodx.app;

import android.graphics.Path;
import java.io.Serializable;
import java.util.ArrayList;

public class SerialPt extends Path implements Serializable {

	private ArrayList pathPoints;
	private int color;
	private float width;

	public SerialPt() {
		super();
		pathPoints = new ArrayList<>();
	}

	public SerialPt(SerialPt p) {
		super(p);
		pathPoints = p.pathPoints;
	}

	public void addPathPoints(float[] points) {
		this.pathPoints.add(points);
	}

	public void saveMoveTo(float x, float y) {
		super.moveTo(x, y);
		addPathPoints(new float[] { x, y });
	}

	public void saveLineTo(float x, float y) {
		super.lineTo(x, y);
		addPathPoints(new float[] { x, y });
	}

	public void saveReset() {
		super.reset();
		pathPoints.clear();
	}

	public void savePoint() {
		if (pathPoints.size() > 0) {
			float[] points = pathPoints.get(0);
			saveLineTo(points[0] + 1, points[1] + 1);
		}
	}

	public void loadPathPointsAsQuadTo() {
		float[] initPoints = pathPoints.get(0);
		this.moveTo(initPoints[0], initPoints[1]);
		for (int j = 1; j < pathPoints.size(); j++) {
			float[] pointSet = pathPoints.get(j);
			this.lineTo(pointSet[0], pointSet[1]);
		}
	}

	public int getColor() {
		return color;
	}

	public void setColor(int color) {
		this.color = color;
	}

	public float getWidth() {
		return width;
	}

	public void setWidth(float width) {
		this.width = width;
	}
}


Selesai....

Baca Juga
Posting Komentar (0)
Lebih baru Lebih lama