Membuat Aplikasi Paint dengan onSaveInstanceState dan onRestore Aplikasi Android
Berikut ini merupakan sebuah aplikasi menggambar yang di operasikan didalam android. Didalam aplikasi yang saya buat, saya menggunakan dua class java dan satu layout yaitu :
- MyCanvas.java
- MainActivity.java
- activity_main.xml
Didalam MyCanvas ini terdapat beberapa variable yang berfungsi untuk mengatur gambar yang akan dibuat. Seperti mBitmap, mCanvas (tempat atau frame untuk menggambar), mPath, mBitmapPaint, dan mDrawPoint. Juga terdapat beberpa method seperti setupPaint() yang berfungsi untuk mengatur path, warna, dan ukuran gambar yang dibuat, onSizeChanged() mengatur posisi atau letak paint, lalu ada onDraw mengatur tentang canvas dan sebagainya.
Berikut Source kodenya:
public class MyCanvas extends View {
Context context;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private boolean mDrawPoint;
int stateToSave=1;
private Paint mPaint;
public MyCanvas(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
System.out.println("init");
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
setupPaint();
}
private void setupPaint()
{
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF000000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4f);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (stateToSave==1) {
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}else {
mBitmap = Bitmap.createScaledBitmap(mBitmap, w, h, true);
}
stateToSave++;
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
System.out.println("on draw");
canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
mDrawPoint=true;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mDrawPoint=false;
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
public void clear(){
mCanvas.drawColor(0, PorterDuff.Mode.CLEAR );
invalidate();
}
private void touch_up() {
if(mDrawPoint == true) {
mCanvas.drawPoint(mX, mY, mPaint);
} else {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
b. MainActivity.java
Didalam MainActivity ini berfungsi untuk mengimplementasikan dari MyCanvas ke activity_main.xml yang didalamnya terdapat fungsi onCreate dan clear (untuk menghapus gambar).
Berikut adalah source codenya :
package com.example.asus.apublic;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private MyCanvas myCanvas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myCanvas = (MyCanvas) findViewById(R.id.canvas);
}
public void clear (View view){
myCanvas.clear();
}
}
c. activity_main.xml
Berisi tentang tampilan dari aplikasi paint yang mana didalamnya terdapat button clear untuk menghapus jika ia di klik maka akan menjalankan method clear() da nada canvas yang akan menjalankan class MyCanvas.java, berikut source codenya:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/inner"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.asus.apublic.MainActivity">
<com.example.asus.apublic.MyCanvas
android:id="@+id/canvas"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="18dp"
android:layout_marginEnd="25dp"
android:drawableTop="@drawable/images"
android:onClick="clear"
android:text="Clear" />
</RelativeLayout>
2. onSaveInstance
Kegunaan dari onSave ini adalah agar saat di rotate data tidak hilang, data tersimpan sementara yang nantinya akan dipanggil kembali didalam onRestore. Berikut adalah penggunaan dari onSave dari aplikasi yang saya buat :
@Override
protected Parcelable onSaveInstanceState()
{
System.out.println("save instance");
Bundle bundle = new Bundle();
bundle.putParcelable("instanceState", super.onSaveInstanceState());
bundle.putParcelable("mBitmap", mBitmap);
bundle.putInt("stateToSave", stateToSave);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state)
{
System.out.println("on restore");
Bundle bundle = (Bundle) state;
mBitmap = bundle.getParcelable("mBitmap");
stateToSave = bundle.getInt("asd");
super.onRestoreInstanceState(bundle.getParcelable("instanceState"));
}
3. AndroidManifest
Agar saat dirotate data dapat disimpan, maka perlu adanya perubahan config didalam manifestnya. Dengan menambahkan (seperti gambar dibawah) pada Activity nya
Untuk source kodenya :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.asus.apublic">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity" android:configChanges="screenSize|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
4. Design main_activity
Dalam tampilan layout, saya menggunakan gambar “images.png” berupa gambar sampah/clear yang gambarnya berada pada folder res-drawable.
5. Kode Keseluruhan di MyCanvas.java
package com.example.asus.apublic;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
/**
* Created by ASUS on 4/14/2018.
*/
public class MyCanvas extends View {
Context context;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private boolean mDrawPoint;
int stateToSave=1;
private Paint mPaint;
public MyCanvas(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
System.out.println("init");
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
setupPaint();
}
private void setupPaint()
{
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF000000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4f);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (stateToSave==1) {
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}else {
mBitmap = Bitmap.createScaledBitmap(mBitmap, w, h, true);
}
stateToSave++;
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
System.out.println("on draw");
canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
mDrawPoint=true;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mDrawPoint=false;
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
public void clear(){
mCanvas.drawColor(0, PorterDuff.Mode.CLEAR );
invalidate();
}
private void touch_up() {
if(mDrawPoint == true) {
mCanvas.drawPoint(mX, mY, mPaint);
} else {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
@Override
protected Parcelable onSaveInstanceState()
{
System.out.println("save instance");
Bundle bundle = new Bundle();
bundle.putParcelable("instanceState", super.onSaveInstanceState());
bundle.putParcelable("mBitmap", mBitmap);
bundle.putInt("stateToSave", stateToSave);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state)
{
System.out.println("on restore");
Bundle bundle = (Bundle) state;
mBitmap = bundle.getParcelable("mBitmap");
stateToSave = bundle.getInt("asd");
super.onRestoreInstanceState(bundle.getParcelable("instanceState"));
}
}
Sumber Referensi :
https://stackoverflow.com/questions/19986071/android-how-to-save-custom-finger-paint-view-on-orientation-change
Membuat Aplikasi Paint dengan onSaveInstanceState dan onRestore Aplikasi Android
Reviewed by Unknown
on
09:26
Rating:
No comments