برای رسم گرافیک دو بعدی نیاز به یک کلاس شخصی سازی شده است که فرزند کلاس view باشد
اگر برنامه ما به مانند بازی ها دارای انیمیشن باشد باید از thread استفاده کنیم تا در بازه های زمانی مشخص گرافیک برنامه را به روز کنیم و دوباره باز طراحی کنیم.
public class ClassName extends View { // required constructor public ClassName(Context context, AttributeSet attrs) { super(context, attrs); } // this method draws on the view @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawing code; } // recall: y-axis increases downward! }
شما میتوانید به راحتی کلاسی را که در layout ساختیه اید در activity مورد نظر خود استفاده کنید. به این مثال توجه کنید:
<!-- res/layout/activity_main.xml --> <RelativeLayout ... tools:context=".MainActivity"> <packageName.ClassName android:layout_width="match_parent" android:layout_height="match_parent" ... /> </RelativeLayout>
متد های کلاس Canvas
متد | شرح |
drawARGB(alpha, r, g, b) | برای پر کردن کادر با رنگ و مقدار آن rgb است |
drawArc(…) | رسم بیضی |
drawBitmap(bmp, x, y, null) | رسم تصویر |
drawCircle(centerX, enter, r, paint) | رسم دایره |
drawLine(x1, y1, x2, y2, paint) | رسم خط |
drawOval(x1, y1, x2, y2, paint) * (requires Android 5.0) drawOval(new RectF(x1, y1, x2, y2), paint) | رسم بیضی |
drawPoint(x, y, paint) | رسم یک نقطه |
drawRect(x1, y1, x2, y2, paint) * (requires Android 5.0) drawRect(new RectF(x1, y1, x2, y2), paint) | رسم مستطیل |
drawRoundRect(x1, y1, x2, y2, rx, ry, paint) * (requires Android 5.0) drawRoundRect(new RectF(x1, y1, x2, y2), rx, ry, paint) | رسم متسطیل با گوشه های مدور |
drawText(“str”, x, y, paint) | رسم متن |
getWidth() getHeight() | برای گرفتن ارتفاع و عرض |
آشنایی با کلاس Paint
اکثر متدهای بالا از کلاس Paint استفاده میکنند، یک رنگ که برای رسم اشکال استفاده میشود.
یک شی از کلاس Paint بسازید و به آن مقدار opacity و رنگ مورد نظر را بدهید، رنگ ها در آن بر اساس RGB است (red, green, blue)
Paint name = new Paint(); name.setARGB(alpha, red, green, blue); // example Paint purple = new Paint(); purple.setARGB(255, 255, 0, 255); purple.setStyle(Style.FILL_AND_STROKE); // FILL, STROKE
کلاس Paint دارای متدهای پرکاربرد دیگری نیز میباشد که از آنها میتوان به موارد زیر اشاره کرد:
getTextBounds, measureText, setAlpha, setAntiAlias, setStrokeWidth, setStyle, setTextAlign, setTextSize, setTypeface
آشنایی با فونت و Typeface
فونت در اندروید typeface نامیده میشود و به راحتی میتوان در Paint یک typeface قرار داد و از آن استفاده کرد:
Typeface.create("font name", Typeface.STYLE); styles: NORMAL, BOLD, ITALIC, BOLD_ITALIC
و یا میتواند بر اساس font family باشد:
Typeface.create(Typeface.FAMILY_NAME, Typeface.STYLE) family names: DEFAULT, MONOSPACE, SERIF, SANS_SERIF
و یا میتواند بر اساس فایل فونت که در داخل سورس برنامه قرار دارد باشد:
Typeface.createFromAsset(getAssets(), "filename")
به نمونه کد زیر توجه کنید:
// example: use a 40-point monospaced blue font Paint p = new Paint(); p.setTypeface( Typeface.create(Typeface.MONOSPACE, Typeface.BOLD)); p.setTextSize(40); p.setARGB(255, 0, 0, 255);
آشنایی با تصاویر Bitmap
برای رسم تصاویر (مثل تصاویر با فرمت .png و .jpg) از کلاس Bitmap استفاده کنید:
Bitmap name = BitmapFactory.decodeResource(getResources(), R.drawable.ID);
مثال: رسم تصویر قلب در نقطه ی (0,0) صفحه:
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.heart); ;(canvas.drawBitmap(bmp, 0, 0, null
همچنین شما میتوانید از یک ورودی استریم (آدرس یک فایل روی شبکه وب) مقدار bitmap بگیرید:
URL url = new URL("http://example.com/myImage.jpg"); Bitmap bmp = BitmapFactory.decodeStream(url.openStream());
حال یک برنامه مینویسیم که در صفحهی اصلی خود custom view به شکل زیر داشته باشد:
- دایرهی قرمز بیرونی ۱۰۰٪ از فضای طول و عرض ویو را گرفته است
- ۵ دایره وجود دارد که همگی وسط چین شدهاند و ۳ تای آنها قرمز و ۲ تای آنها سفید است
- هر دایره ۲۰ درصد کوچکتر از دایرهی قبلی است.
- دایرهی اول (دایرهی قرمز رنگ) ۱۰۰٪ از صفحه است
- دایرهی دوم (سفید) ۸۰٪ از صفحه است
- دایرهی سوم (قرمز) ۶۰٪ از صفحه است
- دایرهی چهارم (سفید) ۴۰٪ از صفحه است
- دایرهی پنجم (قرمز) ۲۰٪ از صفحه است
کد این برنامه به صورت زیر خواهد بود:
public class TargetView extends View { public TargetView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint red = new Paint(); red.setARGB(255, 255, 0, 0); Paint white = new Paint(); white.setARGB(255, 255, 255, 255); int w = canvas.getWidth(), h = canvas.getHeight(); for (int i = 0; i < 5; i++) { canvas.drawOval(new RectF(/*x*/ w*i/10, /*y*/ h*i/10, /*w*/ w*(10-i)/10, /*h*/ h*(10-i)/10), /*paint*/ i % 2 == 0 ? red : white); } } {
برای اینکه به یک view انیمیشن دهید باید آنرا در فواصل زمانی مشخص از نو رسم کنید
در هر رسم دوباره مکان و مقادیر موجود در view شخصیسازی شده را باید تغییر دهید
یک ویو را با فراخوانی متد invalidate میتوان مجبور کرد که خود را دوباره رسم نماید
ولی شما نمیتوانید این کار را در یک حلقه انجام دهید چرا که این موضوع باعث کندی برنامه شما خواهد شد
کد جاوا یک برنامه نمونه
در این بخش یک برنامه ایجاد می کنید که در آن یک نقطه قرمز وجود داشته باشد که در مختصات x/y شروع به حرکت کند و با زدن بر روی یک نقطه از صفحه دایره شروع به برگشت نماید
- تصویر پسزمینه: زرد
- رنگ دایره: قرمز
- اندازه دایره : ۱۰۰ در ۱۰۰ پیکسل
دایره به صورت تصادفی در مختصات x و y شروع به حرکت کند و مقادیر آنها کمتر از ۸۰ پیکسل باشد نقطه باید ۵۰ بار در هر ثانیه باز طراحی شود
برای هندل کردن کلیک کاربر بر روی صفحه یک متد onTouchEvent را فراخوانی میکنیم:
@Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); if (event.getAction() == MotionEvent.ACTION_DOWN) { // code to run when finger is pressed } return super.onTouchEvent(event); {
اگر میخواهید کلیک بر روی دکمهها را هندل کنید ( اگر دستگاه مقصد برنامه داری کیبورد است)، در سازندهی ویو مورد نظر خود دریافت فوکوس کیبورد را بنویسید:
requestFocus(); setFocusableInTouchMode(true);
در کلاس ویو شخصی سازی خود متد onKeyDown/Up را بنویسید؛ هر کلید دارای یک مقدار عددی است مانند KeyEvent.KEYCODE_ENTER
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_X) { // code to run when user presses the X key } return super.onKeyDown(keyCode, event); {
برای جلوگیری از خاموش شدن صفحه از wake lock میتوانید استفاده کنید. برای اینکار در AndroidManifest.xml مقدار زیر را وارد کنید:
<uses-permission android:name="android.permission.WAKE_LOCK" />
در کد جاوایی خود نیز کافیست در activity کد زیر را وارد کنید:
// create the lock (probably in onCreate) PowerManager pwr = (PowerManager) getSystemService(POWER_SERVICE); WakeLock lock = pwr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "my lock"); // turn on the lock (in onResume) lock.acquire(); // turn off the lock (in onPause) lock.release();
برای قرار دادن برنامه در حالت تمام صفحه که دیگر نوتیفیکیشنها و نوار بالای صفحه را نشان ندهد باید کد زیر را در کلاس اکتیویتی خود وارد نمایید:
requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);