نمونه ای از یک Canvas در اندروید
چهارشنبه 18 آذر 1394در این مقاله قصد داریم یک 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 و اجرا نمایید.
خروجی کار به صورت زیر است:
- Android
- 4k بازدید
- 3 تشکر