از Design به Canvas در اندروید

یکی از چالش هایی که تقریباْ همه توسعه دهنده های اندروید با آن سروکار دارند پیاده سازی دیزاین هایی هست که دیزاینر ها آن ها رو با نرم افزار های حرفه ای طراحی کرده اند و طبیعتاْ ما هم در کد باید پیادشون کنیم. ??‍♂️

چالش و انتخاب روش درست چیه؟

معمولا برای پیاده سازی رابط کاربری در اپلیکیشن، از آیکون ها و شکل های هندسی با فرمت های Svg و Png خروجی گرفته می شه و در پروژه قرار داده می شه. گاهی این روش پیاده سازی مشکلاتی رو برای ما به وجود میاره . مشکلاتی مثل بالارفتن حجم برنامه، عدم پشتیبانی کامل Vector از Svg در تبدیل ها، مثل خط های بریده بریده (Dashed lines) و ... ☹️.

اینجاست که به سراغ طراحی شکل های هندسی با canvas میریم که فقط کمی ? مسیر سخت تر و وقت گیرتری نسبت به روش قبلی هست. ولی اصلا جای نگرانی نیست، چون قراره با هم در زیر یک دیزاین پیچیده رو به راحتی و خوشمزگی یک کیک خامه ای بزرگ پیاده سازی کنیم.?

مثلا یک دیزاین پیچیده ?

یک دیزاین پیچیده
یک دیزاین پیچیده


اینجا دو خط بریده بریده، یک شکل منحنی با گرادینت، دو دایره که یکی بریده بریده است و یک آیکون ضربدر داریم.

بریم سراغ پیاده سازی طراحی... ?‍?

چجوری؟

اول اینکه سورس رو میتونید از اینجا بگیرید.

روت پروژه
روت پروژه


داخل پکیج utils یک اینترفیس به اسم CustomViewHelperInterface داریم. در این اینترفیس علاوه بر یک سری متغییر که قراره مقداردهیشون کنیم فاکنشن ها و اکستنشن هایی هم هستن که قرار یه سری محاسبات ریز رو انجام بدن. (اکستنشن ها رو کل پروژه تاثیر نمیذارند و فقط کلاس هایی که این اینترفیس رو پیاده سازی کردند میتونن ازشون استفاده کنند.)

کلاس SampleCurveView اینترفیس مارو پیاده سازی و چهار متغییر مهم رو مقدار دهی کرده.

متغییر هایی که باید مقدار دهی بشن

تکه کدی از کلاس CustomViewHelperInterface
تکه کدی از کلاس CustomViewHelperInterface


متغییر های artboardHeight و artboardWidth طول و عرض artboard دیزاین ما هستن که دیزاینر به عنوان فایل دیزاین داده بهمون. متغییر های targetHeight و targetWidth هم طول و عرض ویویی هست که میخوایید روی آن بکشید.

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

تکه کدی از کلاس SampleCurveView
تکه کدی از کلاس SampleCurveView

با توجه به مقدارهای اولیه باید بتونیم رابطه ای بین نقاط طراحی در دیزاین و ویوی هدف بدست بیاریم. این رابطه در سه مرحله انجام میشه که جلوتر میگم.

مختصات نقاط

اگه تجربه کار با canvas رو داشته باشید میدونید که canvas برای کشیدن هرچیزی نیاز به مختصات داره. یعنی از ما x و y جایی رو میخواد که میخواهیم در آنجا شکل کشیده بشه. مختصات باید ریسپانسیو باشند تا در هر صفحه نمایش دقیقا جایی که باید باشند قرار بگیرند. برای این منظور (مرحله اول) ابتدا مختصات رو در صفحه طراحی بدست بیاریم، (مرحله دوم) بعد درصد مختصات رو نسبت به ابعاد artboard طراحی بدست بیاریم و (مرحله سوم) در آخر از این درصد برای بدست آوردن مختصات نقاط در صفحه نمایش مورد نظر استفاده کنیم.

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

محاسبه درصد مختصات نسبت به ابعاد artboard
محاسبه درصد مختصات نسبت به ابعاد artboard


با متد های زیر هم درصد به دست آمده رو تبدیل می کنیم به طول و عرض ابعاد ویومون.

تبدیل درصد مختصات طراحی به ابعاد view
تبدیل درصد مختصات طراحی به ابعاد view


کیک خامه ای کد

خب نوبت به کیک خامه ایه ?، اونم بعد کلی رابطه و توضیحات


طبق تکه کد بالا از اینترقیس CustomViewHelperInterface دیگه نیازی به استفاده از متدهای محاسباتی گفته شده نداریم. فقط کافیه از اکستنشن های toResponsiveHeight و toResponsiveWidth استفاده کنیم.

canvas?.drawCircle(74.01.toResponsiveWidth(), 360.5.toResponsiveHeight(), r, paint)

برای کشیدن دایره به مختصات دایره ای که تو دیزاین خواسته شده فقط کافیه x و y دایره رو که در دیزاین هست با اکستنشن های toResponsiveWidth و toResponsiveHeight به مختصات جدید تبدیل کنیم. به همین راحتی ?

مقاله کمی طولانی میشه ولی دوست دارم راجب کشیدن Bezier curves هم بگم بهتون. تا اینجا لپ کلام دستتون اومده و ازینجا به بعد فقط جهت تسلط بیشترتون هست.

هر منحنی چهار نقطه اساسی داره. دو End Point و دو Control Point.

Bezier curve
Bezier curve


اگه از ابزار هایی مثل Sketch یا Adobe xd استفاده می کنید بدست آوردن مختصات هریک از این نقطه ها خیلی راحته. روی هر نقطه که کلیک کنید بالا سمت راست مختصات به شما داده میشه و فقط کافیه مختصات رو با اکستنشن ها تبدیل کنید به مختصات جدید برای ویوتون. پیاده سازی طراحی بالا بصورت کامل در کلاس SampleCurveView قرار دارد.

امیدوارم ازین به بعد تو طراحی هاتون دیگه مشکلی با کشیدن اشکال مختلف و عجیب هندسی نداشته باشید ?.

لینک گیتهاب پروژه:

https://github.com/rvhamed/easy_draw