نمونه ای از یک Canvas در اندروید

چهارشنبه 18 آذر 1394

در این مقاله قصد داریم یک canvas طراحی کنیم، که بتوانیم روی صفحه یک متن و یا اشکالی کشیده شود، در واقع نقاشی دو بعدی را در این مقاله انجام می دهیم.

نمونه ای از یک Canvas در اندروید

اندروید یک سری Api هایی را فراهم می کند، که به کاربر اجازه ی طراحی نقاشی های دو بعدی را می دهد

زمانی که ما یک activity داریم از گرافیک دو بعدی استفاده می نماییم، مثل برنامه های بازی های ویدئویی نقاشی روی canvas بهترین راه برای کار با آن است.

قدم اول: یک پروژه ی جدید ایجاد نمایید به صورت زیر:

قدم دوم:نوشتن package مورد نظر است به صورت زیر:

گزینه ی create activity را می زنید و بعد به مرحله ی بعدی می روید:

در مرحله ی بعدی انتخاب اندازه ی آیکون است ، که می توانید از آیکون پیش فرض خود برنامه استفاده نمایید.

در مرحله ی بعدی یک BlankActivity  درست می نمایید.

در مرحله ی بعدی شما نام activity و نام پروژه  و ... را می توانید تغییر دهید:

و نهایتا به صورت زیر پروژه ایجاد می شود:

ما یک activity جدید می سازیم، که یک FrameLayout داخل آن قرار می دهیم، که این FrameLayout یک canvas سفارشی دارد، ما Framelayout را برای لایه ی خارجی قرار می دهیم ، چون که می خواهیم از دکمه برای پاک کردن canvas استفاده نماییم.

Framelayout  به ما اجازه می دهد که بتوانیم خارج از canvas خود یک دکمه برای پاک کردن داشته باشیم.

کد داخل activity_main به صورت زیر است:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:orientation="vertical" >

    <com.javacodegeeks.androidcanvasexample.CanvasView
        android:id="@+id/signature_canvas"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textColor="#FFFFFF" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center"
        android:onClick="clearCanvas"
        android:text="Clear Canvas" />

</FrameLayout>

حالا سراغ کلاس ها می رویم در پوشه ی src یک کلاس جدید می سازیم به صورت زیر:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;

public class AndroidCanvasExample extends Activity {

	private CanvasView customCanvas;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		customCanvas = (CanvasView) findViewById(R.id.signature_canvas);
	}

	public void clearCanvas(View v) {
		customCanvas.clearCanvas();
	}

}

حالا برای کلاس canvas که بخواهیم اشکال دو بعدی را روی صفحه ترسیم نماییم به صورت زیر است:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class CanvasView extends View {

	public int width;
	public int height;
	private Bitmap mBitmap;
	private Canvas mCanvas;
	private Path mPath;
	Context context;
	private Paint mPaint;
	private float mX, mY;
	private static final float TOLERANCE = 5;

	public CanvasView(Context c, AttributeSet attrs) {
		super(c, attrs);
		context = c;

		// we set a new Path
		mPath = new Path();

		// and we set a new Paint with the desired attributes
		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setColor(Color.BLACK);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeJoin(Paint.Join.ROUND);
		mPaint.setStrokeWidth(4f);
	}

	// override onSizeChanged
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);

		// your Canvas will draw onto the defined Bitmap
		mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
		mCanvas = new Canvas(mBitmap);
	}

	// override onDraw
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// draw the mPath with the mPaint on the canvas when onDraw
		canvas.drawPath(mPath, mPaint);
	}

	// when ACTION_DOWN start touch according to the x,y values
	private void startTouch(float x, float y) {
		mPath.moveTo(x, y);
		mX = x;
		mY = y;
	}

	// when ACTION_MOVE move touch according to the x,y values
	private void moveTouch(float x, float y) {
		float dx = Math.abs(x - mX);
		float dy = Math.abs(y - mY);
		if (dx >= TOLERANCE || dy >= TOLERANCE) {
			mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
			mX = x;
			mY = y;
		}
	}

	public void clearCanvas() {
		mPath.reset();
		invalidate();
	}

	// when ACTION_UP stop touch
	private void upTouch() {
		mPath.lineTo(mX, mY);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		float x = event.getX();
		float y = event.getY();

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			startTouch(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:
			moveTouch(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_UP:
			upTouch();
			invalidate();
			break;
		}
		return true;
	}
}

حالا به جزئیات کد می پردازیم:

در کد زیر یک canvas تنظیم می نماییم.

@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {

	    super.onSizeChanged(w, h, oldw, oldh);

	    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

	    mCanvas = new Canvas(mBitmap);

	}

در قسمت بعدی x و y  مختصات یک رویداد است که به منظور ایجاد مسیر حرکت استفاده می نماییم.

@Override

	public boolean onTouchEvent(MotionEvent event) {
	    float x = event.getX();
	    float y = event.getY();
	    switch (event.getAction()) {
	    case MotionEvent.ACTION_DOWN:
	        startTouch(x, y);
	        invalidate();
	        break;
	    case MotionEvent.ACTION_MOVE:
	        moveTouch(x, y);
	        invalidate();
	        break;
	    case MotionEvent.ACTION_UP:
	        upTouch();
	        invalidate();
        break;
	    }
	    return true;
	}

مختصات رویداد x,y را به مسیر حرکت انتقال می دهیم.

private void moveTouch(float x, float y) {
	    float dx = Math.abs(x - mX);
	    float dy = Math.abs(y - mY);
	    if (dx >= TOLERANCE || dy >= TOLERANCE) {
	        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
	        mX = x;
	        mY = y;
	    }
	}

حالا داخل رویداد OnDraw() ، canvas مورد نظر را صدا می زنیم.

// override onDraw
	@Override
	protected void onDraw(Canvas canvas) {
	    super.onDraw(canvas);
	    canvas.drawPath(mPath, mPaint);
	}

حالا پروژه را Build و اجرا نمایید.

خروجی کار به صورت زیر است:

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید