Jetpack Compose چیست؟ – معرفی جت پک کامپوز + کاربرد و قابلیت ها
این روزها ظاهر و طراحی «رابط کاربری» (UI) اپلیکیشنهای اندرویدی به اندازه عملکرد این اپلیکیشنها برای کاربران اندروید حائز اهمیت است. اپلیکیشنهایی با رابط کاربری جذاب از اقبال بیشتری نیز برخوردار هستند. گوگل نیز به عنوان ارائه دهنده سیستم عامل اندروید با معرفی ابزار Jetpack Compose گام بلندی در بحث بهبود «تجربه کاربری» (User Experience | UX) اپلیکیشنهای اندرویدی برداشته است. Jetpack Compose ابزاری مدرن برای طراحی رابط کاربری اپلیکیشنهای اندرویدی محسوب میشود که جایگزین کیت توسعه قدیمی رابط کاربری اندروید شده است. در این نوشتار به این سوال پاسخ داده میشود که Jetpack Compose چیست و چه کاربردهایی دارد.
همچنین، ضمن مقایسه Jetpack Compose و روش سنتی توسعه رابط کاربری اندروید به این سوال پاسخ داده شده است که دلیل انتخاب Jetpack Compose چیست و چرا توسعهدهندگان این ابزار را برای طراحی رابط کاربری انتخاب میکنند. در ادامه این مطلب نیز موارد مهمی همچون ساختار Jetpack Compose، مزایا و معایب آن و مهمترین قابلیتهای آن در امر توسعه رابط کاربری مورد بررسی قرار گرفتهاند. در انتها نیز ضمن پاسخ به این سوال که پیشنیاز یادگیری Jetpack Compose چیست ، به بررسی نحوه نصب و آموزش Jetpack Compose به صورت گام به گام پرداخته شده است.
Jetpack Compose چیست ؟
Jetpack Compose ابزاری مُدرن برای طراحی رابط کاربری اپلیکیشنهای اندرویدی به حساب میآید. این ابزار نخستین بار توسط گوگل در مراسم I/O سال ۲۰۱۹ میلادی (۱۳۹۸ شمسی) معرفی شد.
در سالهای اخیر تغییرات شگرفی در بخشهای مختلف برنامه نویسی اندروید رخ داده است. از جمله این موارد میتوان به تغییر ساختار اپلیکیشنها، زبان برنامه نویسی مورد استفاده، نرم افزارهای برنامه نویسی اندروید، ابزارها و کتابخانههایی اشاره کرد که موجب بهبود عملکرد و افزایش سرعت توسعه اپلیکیشنهای اندرویدی شدهاند. تنها «کیت توسعه رابط کاربری» (User Interface Toolkit) در این سالها تقریباً بدون تغییر باقی مانده بود. بنابراین، گوگل Jetpack Compose را به عنوان ابزاری مدرن و روشی جدید برای توسعه رابط کاربری اندروید معرفی کرد.
توسعه رابط کاربری اندروید به کمک Jetpack Compose سادهتر، سریع تر، توسعهپذیرتر و بدون نیاز به کد نویسی زیاد است. بنابراین، استفاده از این ابزار مدرن میتواند به بهبود «تجربه کاربری» (User Experience | UX) منجر شود.
دلیل پیدایش Jetpack Compose چیست ؟
امروزه انتظارات کاربران در خصوص رابط کاربری اپلیکیشنهای اندروید افزایش یافته است. در نتیجه، استفاده از روش سنتی توسعه رابط کاربری مبتنی بر کدهای XML دیگر پاسخگوی نیاز کاربران نیست و باید از ابزارهای جدیدتر معرفی شده در این حوزه استفاده کرد.
گوگل برای پاسخ به این نیاز برنامهنویسان ابزار مدرن Jetpack Compose را معرفی کرده است. این ابزار علاوه بر ساده کردن فرایند طراحی رابط کاربری، سرعت فرایند توسعه را نیز افزایش داده است. همچنین، بسیاری از خطاها و باگهای موجود در روال سابق طراحی رابط کاربری نیز برطرف کرده شدهاند.
مهم ترین کاربردهای Jetpack Compose چیست؟
Jetpack Compose بازنویسی کاملی از کیت توسعه رابط کاربری اندروید ارائه کرده است. توسعه این ابزار توسط گوگل اقدام بسیار مهمی در صنعت توسعه اپلیکیشنهای اندرویدی به حساب میآید. در نتیجه، هر برنامهنویسی باید بداند که Jetpack Compose چیست و چه کاربردهایی دارد.
در این بخش از نوشته به این سوال پاسخ داده خواهد شد که مهمترین کاربردهای Jetpack Compose چیست و چرا گوگل این ابزار مدرن توسعه رابط کاربری را معرفی کرده است. علاوه بر این، چالشهای توسعه رابط کاربری به روش سنتی با کدهای XML و راهحل ارائه شده توسط Jetpack Compose نیز در این قسمت مورد بررسی قرار گرفته است. در ادامه، مهمترین چالشهای استفاده از کیت توسعه رابط کاربری قدیمی اندروید آورده شده است.
وابستگی بیش از حد کیت توسعه رابط کاربری اندروید به سیستم عامل
منظور از وابستگی بیش از حد کیت توسعه رابط کاربری اندروید به سیستم عامل این است که اگر تیم توسعه اندروید موفق به ایجاد تغییراتی در بحث رابط کاربری اندروید شود، باید برای دریافت این تغییرات تا انتشار نسخه جدید سیستم عامل اندروید صبر کرد.
نسخه جدید سیستم عامل اندروید نیز سالی یک بار ارائه میشود. جداسازی رابط کاربری از سیستم عامل اندروید رفع خطاها و اشکالات به وجود آمده را آسانتر و سریعتر میکند. علاوه بر این، دریافت بروزرسانیها برای رابط کاربری نیز تسهیل میشود.
منسوخ شدن برخی از API های حیاتی اندروید
در حال حاضر تجربیات و انتظارات برنامهنویسان در بحث برنامه نویسی اندروید تفاوت زیادی با آن چه دارد که اولین بار در زمان معرفی سیستم عامل اندروید یعنی سال ۲۰۰۸ میلادی (۱۳۸۷ شمسی) وجود داشت. با معرفی Android Jetpack هسته اصلی اندروید به کتابخانههای قابل نگهداری کوچکتری تجزیه شد.
در واقع Android Jetpack راهکاری جدید برای توسعه آسانتر اپلیکیشنهای اندرویدی به حساب میآید. با وجود معرفی این ابزار، سیستم نمایش رابط کاربری اندروید همچنان تغییر چندانی نکرد که همین مورد معرفی الگوها و تغییرات جدید را دشوار ساخت. در نتیجه، گوگل Jetpack Compose را برای رفع مشکلات موجود در طراحی رابط کاربری معرفی کرد.
پیچیدگی فرایند توسعه رابط کاربری برای برنامه نویسان
فرایند فعلی طراحی رابط کاربری شامل تعریف Viewهای برنامه در فایل XML و سپس، افزودن «منطق کسب و کار» (Business Logic) به رابط کاربری با استفاده از کدهای جاوا یا کاتلین است. در انتها نیز برای استفاده از عناصر رابط کاربری یا اعمال تغییرات بر روی آنها به کمک شناسهها میتوان به این ویوها ارجاع داد.
مدیریت دشوار State ها در اندروید
stateها در Jetpack Compose وضعیت «کامپوننتهای» (Component) برنامه را مشخص میکنند و برای تغییر وضعیت کامپوننتهای برنامه باید از آنها استفاده کرد.
مدیریت stateها در رابط کاربری همواره یکی از دغدغههای برنامهنویسان اندروید بوده است، زیرا ویوهای برنامه حالت خود را نیز ذخیره میکنند. بررسی وضعیت stateها و همگام بودن آنها در «ویوها» (Views)، «ویو مدلها» (View Models) و «ارائهدهندهها» (Presenters) به عنوان چالشی جدی در الگوی معماری MVC مطرح میشود. در نتیجه، همین مورد به عنوان منشاً اکثر خطاها و باگهای برنامههای اندرویدی شناخته میشود.
بررسی مهمترین ساختارهای Jetpack Compose
Jetpack Compose نیز همانند سایر تکنولوژیهای معرفی شده در زمینه توسعه اپلیکیشنهای اندرویدی دارای ساختارها و مفاهیم جدیدی است. برای درک و شناخت بهتر این ابزار مدرن توسعه رابط کاربری، آشنایی با مفاهیم و ساختارهای اصلی مورد استفاده در آن ضروری است.
در این بخش از نوشته سعی شده است تا اصلیترین مفاهیم و ساختارهای موجود در Jetpack Compose مورد بررسی قرار گیرند.
ساختار تابع Composable
بسیاری از افراد تازه کار با این سوال مواجه هستند که منظور از کلمه کلیدی @Composable
در Jetpack Compose چیست و چه کاربردی دارد.
ساخت مولفهها و کامپوننتهای رابط کاربری در Jetpack Compose به کمک توابعی صورت میگیرد که با عبارت @Composable
«حاشیهنویسی» (Annotation) شده باشند. این حاشیهنویسی به کامپایلر اطلاع میدهد که این تابع برای تبدیل دادهها به مولفههای رابط کاربری در نظر گرفته شده است. در واقع، بر خلاف رویکرد سنتی توسعه رابط کاربری اندروید در Jetpack Compose از توابع برای طراحی رابط کاربری استفاده میشود. قطعه کد زیر نحوه پیادهسازی توابع Composable را نشان میدهد.
@Composable
fun App(appData: AppData) {
val derivedData = compute(appData)
Header()
if (appData.isOwner) {
EditButton()
}
Body {
for (item in derivedData.items) {
Item(item)
}
}
}
در قطعه کد بالا تابع App
دادهها را به عنوان پارامتر ورودی از کلاس appData
دریافت میکند. نکتهای که باید به آن توجه داشت این است که دادههای مورد استفاده در توابع Composable
از نوع «غیرقابل تغییر» (Immutable) هستند. با استفاده از این توابع میتوان بخشهای مختلف رابط کاربری را پیادهسازی و به کمک زبان برنامهنویسی کاتلین و ساختارهای موجود در آن نیز منطق مورد نظر را به رابط کاربری اضافه کرد.
رویکرد اعلانی رابط کاربری
عبارت Declarative یا اعلانی یک کلمه کلیدی مهم به شمار میرود.
اما منظور از رویکرد اعلانی در Jetpack Compose چیست و چه تفاوتی با رویکردهای قبلی دارد. همانطور که پیشتر نیز بیان شد، برای بررسی رویکرد برنامه نویسی اعلانی باید آن را با رویکرد برنامه نویسی دستوری مقایسه کرد. در ادامه، این دو رویکرد در طراحی رابط کاربری با یکدیگر مقایسه شدهاند. برای این منظور «آیکون» (Icon) یک برنامه مدیریت ایمیل را در نظر بگیرید.
در صورتی که هیچ پیام جدیدی وجود نداشته باشد، این آیکون یک پاکت خالی را نشان میدهد و در صورت وجود چند پیام آیکون برنامه شامل تعدادی کاغذ درون این پاکت خواهد بود. همچنین، اگر تعداد پیامها بیش از ۱۰۰ مورد باشد نیز علامت آتش بر روی آیکون برنامه نشان داده میشود. در تصویر زیر حالتهای مختلف این آیکون نشان داده شده است.
برای پیادهسازی این ساختار به کمک رویکرد برنامه نویسی دستوری باید حالتهای مختلف را در نظر گرفت. در ادامه، قطعه کد مربوط به پیادهسازی این بخش به کمک رویکرد برنامه نویسی دستوری آورده شده است.
fun updateCount(count: Int) {
if (count > 0 && !hasBadge()) {
addBadge()
} else if (count == 0 && hasBadge()) {
removeBadge()
}
if (count > 99 && !hasFire()) {
addFire()
setBadgeText("99+")
} else if (count 0 && !hasPaper()) {
addPaper()
} else if (count == 0 && hasPaper()) {
removePaper()
}
if (count
در قطعه کد بالا، تعداد پیامهای دریافتی به کمک متغیر count
سنجیده میشود. برای تعیین آیکون مناسب برنامه باید حالتهای مختلف را در نظر گرفت که پیادهسازی این منطق به دلیل وجود حالتهای مختلف کمی دشوار است. در ادامه، پیادهسازی همین عملکرد به کمک رویکرد برنامه نویسی اعلانی ارائه شده است.
@Composable
fun BadgedEnvelope(count: Int) {
Envelope(fire=count > 99, paper=count > 0) {
if (count > 0) {
Badge(text="$count")
}
}
}
در نمونه کد بالا، برای پیادهسازی عملکرد مورد نظر ۳ شرط کلی در نظر گرفته شده است.
- اگر مقدار count
بیشتر از ۹۹ باشد، آیکون آتش، نشان داده شود.
- اگر مقدار count
بیشتر از صفر باشد، آیکون کاغذ نشان داده شود.
- اگر مقدار count
بیشتر از صفر باشد، عدد مربوط به تعداد پیامها نیز همراه آیکون کاغذ نشان داده شود.
پیادهسازی رابط کاربری به کمک رویکرد برنامه نویسی اعلانی آسانتر و بدون نیاز به کد نویسی زیاد است، زیرا در این رویکرد نیازی به مشخص کردن وضعیت قبلی نیست و تنها باید حالت فعلی را مشخص کرد.
منظور از کپسوله سازی در Jetpack Compose چیست ؟
«کپسوله سازی» (Encapsulation) یکی از مفاهیم مهم در Jetpack Compose است. کپسولهسازی در مفاهیم شی گرایی نیز مطرح میشود و به این معنا است که خصوصیات و رفتارهای یکی شی تنها باید از طریق متدهای درون کلاس قابل دسترسی باشند و هر گونه دسترسی از دنیای بیرون به آن امکان پذیر نباشد.
این نکته را باید هنگام طراحی APIهای عمومی توابع Composable در نظر گرفت، زیرا APIهای عمومی توابع Composable تنها شامل مجموعه پارامترهای دریافتی آن هستند و کنترلی بر روی آنها وجود ندارد.
اصول برنامه نویسی شی گرا — به زبان ساده
منظور از ترکیب مجدد در Jetpack Compose چیست؟
به فرایند فراخوانی مجدد توابع Composable در Jetpack Compose «ترکیب مجدد» (Recomposition) گفته میشود. این اتفاق در زمان تغییر ورودیهای تابع رخ میدهد. سوالی که برای بسیاری از افراد وجود دارد این است که مزیت ترکیب مجدد در Jetpack Compose چیست و چگونه این قابلیت به بهبود عملکرد برنامه منجر میشود.
برای پاسخ به این سوال باید گفت که Jetpack Compose بر اساس ورودیهای جدید تنها توابعی را مجدداً فراخوانی میکند که تغییر کردهاند و سایر توابع بدون تغییر باقی میمانند. در نتیجه، همین عدم نیاز به فراخوانی سایر توابع به بهبود عملکرد، کارایی و سرعت اپلیکیشن منجر میشود.
مزایا و معایب Jetpack Compose چیست ؟
در این بخش از نوشته به شرح مختصر مزایا و معایب Jetpack Compose در توسعه اپلیکیشنهای اندرویدی پرداخته شده است. ابتدا بهتر است به این سوال پاسخ داده شود که مزایای Jetpack Compose چیست و چرا استفاده از آن نسبت به رویکرد سنتی توسعه UI ارجحیت دارد.
در ادامه، مزایای Jetpack Compose در توسعه رابط کاربری اندروید فهرست شده است.
مزایای Jetpack Compose چه هستند؟
مزایای Jetpack Compose به شرح زیر هستند.
- کاهش هزینه توسعه
- بهبود کارایی و عملکرد توسعهدهندگان
- قابلیت همکاری بالا
- امکان اشتراک گذاری کدها بین اندروید، وب و دسکتاپ
- منابع یادگیری فراوان
- رویکرد «اعلانی» (Declarative)
- افزایش سرعت توسعه
معایب Jetpack Compose کدامند؟
برخی از معایب جت پک کامپوز در ادامه فهرست شدهاند.
- نوظهور بودن
- جامعه توسعهدهندگی کوچک
- سرعت پایین رابط کاربری
- پشتیبانی پایین توسط سایر ابزارهای توسعه
پیش نیاز یادگیری Jetpack Compose چیست ؟
Jetpack Compose ابزاری مدرن برای توسعه رابط کاربری اندروید به حساب میآید که فرایند توسعه را بسیار آسان میکند. این ابزار در حال حاضر توسط برنامهنویسان و شرکتهای مطرحی همچون گوگل، Airbnb و توییتر در سطح جهان به کار برده میشود.
برای استفاده از این ابزار مدرن، مطمئناً داشتن دانش و درک برنامه نویسی اندروید لازم است و نیاز هست که تجربه توسعه اپلیکیشن اندروید را داشته باشید. علاوه بر این، داشتن پیشنیازهای زیر برای استفاده بهتر از این ابزار ضروری است.
- در حال حاضر، Jetpack Compose مختص زبان کاتلین ارائه شده است. در نتیجه، باید با زبان برنامه نویسی کاتلین کاملاً آشنا باشید.
- باید از آخرین نسخه «اندروید استودیو» (Android Studio) استفاده کنید، زیرا ساخت Compose Activity تنها در آخرین نسخه اندروید استودیو در دسترس است.
- داشتن اطلاعات در خصوص شیوههای طراحی رابط کاربری اندروید نیز میتواند مفید باشد.
آموزش نصب Jetpack Compose
بعد از آشنایی با مفهوم Jetpack Compose و ویژگیها، امکانات و کاربردهای آن در این بخش از نوشته، نحوه ایجاد پروژه اندرویدی مبتنی بر Jetpack Compose مورد بررسی قرار خواهد گرفت. علاوه بر این، نحوه افزودن Jetpack Compose به پروژههای فعلی نیز آموزش داده شده است.
ایجاد پروژه جدید Jetpack Compose در اندروید استودیو
برای ایجاد پروژه اندرویدی مبتنی بر Jetpack Compose باید از آخرین نسخه اندروید استودیو استفاده کرد. برای این منظور در گام نخست باید همانند تصویر زیر در صفحه Welcome to Android Studio
بر روی دکمه New Project
کلیک کنیم.
در پنجره جدید باز شده بر روی گزینه Empty Compose Activity
کلیک کرده و دکمه Next
را بزنید.
بعد از این صفحه در پنجره مربوط به اطلاعات پروژه نام، نام بسته، محل ذخیرهسازی و حداقل نسخه SDK را تعیین کنید.
با کلیک بر روی دکمه Finish
پروژه اندرویدی مبتنی بر Jetpack Compose راهاندازی شده و آماده اجرا است.
افزودن Jetpack Compose به پروژه فعلی
برای افزودن Jetpack Compose به پروژه فعلی و استفاده از امکانات آن، نیاز به اعمال یکسری تغییرات در پروژه فعلی وجود دارد. حداقل نسخه SDK سازگار با Jetpack Compose نسخه ۲۱ است و باید حتماً این مورد را در نظر داشت. برای افزودن Jetpack Compose به پروژه فعلی در گام نخست باید به سراغ فایل build.gradle
رفت و کدهای زیر را در آن قرار داد.
android {
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.2.0'
}
}
سپس، در بخش مربوط به dependencies
باید موارد زیر را اضافه کرد.
dependencies {
implementation 'androidx.activity:activity-compose:1.3.1'
implementation "androidx.compose.animation:animation:1.1.1"
implementation "androidx.compose.foundation:foundation:1.1.1"
implementation "androidx.compose.material:material:1.1.1"
implementation "androidx.compose.runtime:runtime:1.1.1"
implementation "androidx.compose.ui:ui:1.1.1"
}
تمام تغییرات مورد نظر برای استفاده از Jetpack Compose در پروژه اندرویدی اعمال شدند و تنها با استفاده از کدهای کاتلین در Activity اصلی برنامه میتوان رابط کاربری اپلیکیشن را مبتنی بر این ابزار جدید طراحی پیادهسازی کرد.
آموزش گام به گام Jetpack Compose
در این بخش از نوشته به این سوال پاسخ داده خواهد شد که چگونه میتوان از Jetpack Compose در طراحی رابط کاربری پروژههای اندرویدی استفاده کرد. بعد از نصب و انجام تنظیمات اولیه به منظور استفاده از Jetpack Compose در اندروید استودیو به صورت گام به گام، نحوه پیادهسازی پروژه اندرویدی مبتنی بر این ابزار مورد بررسی قرار خواهد گرفت.
ایجاد پروژه Hello World در Jetpack Compose
ایجاد پروژه چاپ عبارت معروف «Hello World» یا «سلام دنیا» اولین چیزی است که برنامهنویسان در هنگام یادگیری زبان برنامه نویسی جدید فرا میگیرند. در این بخش نیز ابتدا یاد خواهیم گرفت که چگونه به کمک Jetpack Compose عبارت Hello World را به روی صفحه نمایش گوشی اندرویدی چاپ کنیم.
برای چاپ شدن عبارت Hello World بر روی صفحه باید کد زیر را در Activity اصلی برنامه قرار داد.
class SimpleTextActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContent
{
SimpleText("Hello World")
}
}
}
@Composablefun SimpleText(text: String) {BasicText(text)}
در نمونه کد بالا، درون بدنه کلاس SimpleTextActivity
متد onCreate
قرار داده شده است. تا اینجای کار همه چیز مشابه قبل است و طراحی رابط کاربری به کمک کیت توسعه قدیمی UI اندروید نیز به همین صورت انجام میگرفت.
وجه تمایز Jetpack Compose و روش سنتی توسعه رابط کاربری استفاده از متد setContent
است که درون این بخش امکان تعریف کامپوننتها و متُدهای مختلف وجود دارد. تابع SimpleText
از نوع @Composable
به متد setContent
ارسال شده است و در نتیجه، متن Hello World
به کمک آن روی صفحه نمایش داده میشود.
توابع @Composable
اصلیترین بخش برای تعریف رابط کاربری در Jetpack Compose محسوب میشوند. این توابع ساختار بلوکی دارند و از چندین تابع @Composable
دیگر تشکیل شدهاند. در مثال بالا، تابع SimpleText
به عنوان ورودی متغیری از نوع «رشته» (String) دریافت میکند.
درون بدنه این تابع از متد BasicText
استفاده شده است که یکی از متدهای از پیش تعریف شده Jetpack Compose است. علاوه بر این، برای راحتی کار و عدم نیاز به اجرای مجدد برنامه به منظور نمایش خروجی میتوان از متد @Preview
قبل از تعریف تابع استفاده کرد. در ادامه، نحوه استفاده از متد @Preview
در Jetpack Compose آورده شده است.
@Preview @Composable fun SimpleTextPreview() { SimpleText("Hello World!") }
بعد از تعریف متد @Preview
برای توابع میتوان خروجی نمایشی را همانند تصویر زیر در اندروید استودیو مشاهده کرد.
با استفاده از این قابلیت میتوان بدون نیاز به اجرای برنامه بر روی شبیهساز اندرویدی خروجی نهایی را مشاهده کرد و در صورت نیاز آن را تغییر داد. این ویژگی علاوه بر سرعت بخشیدن به توسعه رابط کاربری موجب افزایش بهرهوری نیز میشود.
Modifiers در Jetpack Compose
بعد از آشنایی با نحوه نمایش متن در برنامه اندرویدی با استفاده از ساختار Jetpack Compose در این بخش به این سوال پاسخ داده خواهد شد که کاربرد Modifiers در Jetpack Compose چیست و چگونه میتوان از آن استفاده کرد.
با استفاده از Modifiersها میتوان ویژگیهایی نظیر رنگ پسزمینه و «حاشیه» (Padding) را به متن افزود و ظاهر متن را زیباتر کرد. کد زیر چگونگی استفاده از Modifiers برای تغییر رنگ پس زمینه و افزودن حاشیه به متن در Jetpack Compose را نشان میدهد.
@Composable fun SimpleText(text: String) {
BasicText(
text = text,
modifier = Modifier.background(Color.LightGray).padding(16.dp)
)
}
در نمونه کد بالا، Modifiers به متد BasicText
اضافه شده و ویژگیهای مورد نظر برای زیباسازی متن را مشخص کرده است. این مثال، از متدهای background
و padding
به ترتیب برای تعیین رنگ پس زمینه و حاشیه متن استفاده کرده است.
نکته جالب توجه در خصوص Modifiers این است که ترتیب متدها در آن بر خروجی تاثیر میگذارد. در مثال بالا، ابتدا ویژگی background
و بعد مشخصه padding
قرار گرفته است. در نتیجه، همان طور که در تصویر بالا مشخص است این مورد سبب میشود که رنگ پس زمینه به نواحی حاشیه متن نیز اعمال شود. برای این که رنگ پس زمینه تنها به متن اعمال شود کافی است تا جای این دو مشخصه تغییر کند. در نمونه کد زیر، ترتیب دو ویژگی background
و padding
تغییر کرده است.
@Composable fun SimpleText(text: String) {
BasicText(
text = text,
modifier = Modifier
.padding(16.dp)
.background(Color.LightGray)
)
}
با تغییر ترتیب دو ویژگی فوق خروجی برنامه به صورت زیر خواهد بود.
نمایش دیالوگ هشدار در Jetpack Compose
دیالوگها یکی از بخشهای بنیادی در هر اپلیکیشنی محسوب میشوند و برای نمایش پیغامهای هشدار یا خطا مورد استفاده قرار میگیرند. بعد از آشنایی با مفاهیم ابتدایی در Jetpack Compose در این بخش نحوه استفاده از «دیالوگ هشدار» (Alert Dialog) مورد بررسی قرار خواهد گرفت و مثال بسیار خوبی برای درک بهتر رویکرد «برنامه نویسی اعلانی» (Declarative Programming) خواهد بود.
برای درک بهتر رویکرد «برنامه نویسی اعلانی» (Declarative Programming) میتوان از مقایسه آن با رویکرد «برنامه نویسی دستوری» (Imperative Programming) استفاده کرد. زیرا، یکی از بهترین راهها برای درک یک مفهوم استفاده از خاصیت تضاد است. رویکرد برنامه نویسی دستوری بیشتر به چگونه انجام شدن عملی میپردازد. به عنوان مثال، چگونه باید رابط کاربری خاصی را رندر (Render) کرد. در ادامه، نحوه پیادهسازی دیالوگ هشدار در اندروید آورده شده است.
val alertDialog = AlertDialog.Builder(context).setTitle("CODE Magazine!").setMessage("Isn't it amazing?")
// Somewhere else in code if (some_condition_is_met()) {alertDialog.show()}
// Somewhere else in code if (some_other_condition_is_met()) {alertDialog.dismiss()}
از سوی دیگر، رویکرد برنامه نویسی اعلانی به دنبال پاسخ به این سوال است که برای انجام عملی خاص چه کاری باید انجام شود. به عنوان مثال، برای ساخت رابط کاربری چه چیزی باید رندر شود. قطعه کد زیر نحوه نمایش دیالوگ هشدار به کمک Jetpack Compose را نشان میدهد.
@Composablefun AlertDialogComponent() {
if (some_condition_is_met()) {
AlertDialog(title = {Text("CODE Mag!")}, text = {Text(text = "Howdy!")})
}
}
در نمونه کد بالا، در صورت برقرار بودن شرط مورد نظر از AlertDialog
پیش فرض موجود در Jetpack Compose برای نمایش دیالوگ هشدار استفاده میشود. در این روش برای بهروزرسانی وضعیت رابط کاربری هیچ کدام از توابع show
یا dismiss
فراخوانی نمیشوند. علاوه بر این، کد برنامه دیگر به کلاس context در اندروید وابسته نیست.
کاربرد State در Jetpack Compose چیست؟
Jetpack Compose با معرفی قابلیتی تحت عنوان State به دغدغه بسیاری از برنامهنویسان اندروید پایان داد. Stateها در Jetpack Compose وضعیت کامپوننتهای برنامه را مشخص میکنند و با استفاده از آنها به آسانی میتوان رابط کاربری اپلیکیشن را بروزرسانی کرد.
در این بخش از نوشته به سوال پاسخ داده خواهد شد که کاربرد State در Jetpack Compose چیست و چگونه میتوان از آن در اپلیکیشن اندرویدی استفاده کرد. کد زیر به صورت عملی نحوه استفاده از State و کاربرد آن در Jetpack Compose را نشان میدهد.
@Composable
fun ButtonClickComponent() {
var showPopup by remember {
mutableStateOf(false)
}
val color = if (showPopup) {
Color.Green
} else {
Color.Red
}
val colors = ButtonDefaults.buttonColors(backgroundColor = color)
Button(
onClick = { showPopup = true },
colors = btnColors
) {
Text(text = "Click Me")
}
}
در نمونه کد ارائه شده در بالا، متغیری از نوع «تغییر پذیر» (mutable) با نام showPopup
تعریف شده است. علاوه بر این، در کنار این متغیر کلمات کلیدی جالب و جدیدی همچون remember
و mutableStateOf
نیز دیده میشوند که احتمالاً در برنامه نویسی اندروید کمتر با آنها مواجه شدهاید.
واکنش به تغییر State از ویژگیهای اصلی Jetpack Compose است. با تغییر مقدار متغیر showPopup
تمام کامپوننتها و بخشهایی از برنامه که از این متغیر استفاده کردهاند، به صورت خودکار مجدداً ترسیم و بروزرسانی میشوند. در مثال فوق، با کلیک کاربر بر روی دکمه مقدار متغیر showPopup
تغییر میکند و در نتیجه، رنگ این دکمه سبز میشود.
امروزه علاوه بر Jetpack Compose فریمورکهایی همچون «فلاتر» (Flutter) و «ریکت نیتیو» (React Native) نیز از رویکرد «مدیریت حالت» (State Managment) برای بروزرسانی رابط کاربری استفاده میکنند.
طراحی Layout در Jetpack Compose
در این بخش از نوشته نحوه پیادهسازی یک کامپوننت ساده مورد بررسی قرار خواهد گرفت که شامل دو متن و یک تصویر است. تصویر زیر محل قرارگیری اجزای این کامپوننت نشان داده شده است.
تمام اپلیکیشنهای اندرویدی از کنار هم قرار گرفتن چندین کامپوننت همانند کامپوننت فوق ساخته میشوند. برای راحتتر شدن فرایند طراحی این کامپوننت در Jetpack Compose باید آن را به چند بخش کوچکتر تقسیم کرد. در تصویر زیر کامپوننت فوق به بخشهای کوچکتر تقسیم شده است.
با توجه به تصویر فوق، این کامپوننت از یک ردیف یا Row تشکیل شده است که این ردیف نیز شامل یک تصویر یا ImageView و یک ستون یا Column است. در نهایت، ستون مورد نظر نیز از دو متن یا Text تشکیل شده است. برای پیادهسازی این کامپوننت به کمک روش سنتی توسعه رابط کاربری در اندروید باید از عناصری همچون LinearLayout
یا RelativeLayout
استفاده کرد.
برای این منظور باید دانست که هر کدام از عناصر رابط کاربری در روش سنتی دقیقاً چه معادلی را در ساختار Jetpack Compose دارند. در نتیجه، میتوان با مراجعه به این سایت (+) به آسانی معادل عناصر رابط کاربری را در ساختار Jetpack Compose به دست آورد.
به عنوان مثال، برای پیادهسازی کامپوننت فوق در Jetpack Compose به جای استفاده از LinearLayout
میتوان از Row
یا Column
با توجه به شرایط استفاده کرد. در ادامه، کد مربوط به پیادهسازی این کامپوننت به کمک Jetpack Compose آورده شده است.
@Composable
fun ImageWithTitleSubtitleComponent(
title: String,
subtitle: String,
imageUrl: String
) {
Card(
shape = RoundedCornerShape(4.dp),
modifier = Modifier.fillParentMaxWidth().padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth()
.padding(16.dp)
) {
// Assume we created a component to render an Image. NetworkImage(imageUrl)
Column(
modifier = Modifier.padding(start = 16.dp)
) {
BasicText(title) BasicText(subtitle)
}
}
}
}
پیاده سازی List به کمک Jetpack Compose
لیست ویو (ListView) یکی از ویجتهای پرکاربرد در اپلیکیشنهای اندرویدی است. با استفاده از این ویجت میتوان لیستی از آیتمها را در اپلیکیشن نمایش داد. از جمله کاربردهای لیست ویو میتوان به استفاده از آن در اپلیکیشنهای مربوط به نمایش لیست مخاطبین، لیست محصولات و لیست شهرها اشاره کرد.
برای ساخت لیستی از عناصر به کمک Jetpack Compose باید به این سوال پاسخ داد که معادل ListView در Jetpack Compose چیست و چگونه باید از آن استفاده کرد. با استفاده از LazyColumn
میتوان لیستی از عناصر را در Jetpack Compose پیادهسازی کرد. نمونه کد زیر، نحوه پیادهسازی لیستی از عناصر را به کمک LazyColumn
در Jetpack Compose نشان میدهد.
@Composable
fun ListComponent(list: List) {
LazyColumn(modifier = Modifier.fillMaxHeight()) {
items(
items = list,
itemContent = { listItem -> ImageWithTitleSubtitleComponent(
title = listItem.title,
subtitle = listItem.subtitle,
imageUrl = listItem.imageUrl
)}
)
}
}
با بررسی نمونه کد بالا و کد مربوط به پیادهسازی لیست ویو به روش سنتی در اندروید میتوان متوجه کاهش قابل ملاحظه کدها شد. کاهش میزان کدها و افزایش خوانایی از نکات مثبت استفاده از Jetpack Compose در طراحی رابط کاربری اپلیکیشنهای اندرویدی است.
طراحی رابط کاربری اپلیکیشن اندروید با Jetpack Compose
از ابتدای نوشته با بررسی مفاهیم مختلف به این سوال پاسخ داده شد که Jetpack Compose چیست و چرا باید از آن در طراحی رابط کاربری استفاده کرد. در ادامه به کمک مفاهیم آموخته شده یک صفحه از رابط کاربری یک اپلیکیشن واقعی به طور کامل پیادهسازی خواهد شد.
صفحه طراحی شده در این بخش در واقع فهرستی از تصاویر و اطلاعات شخصیتهای ابر قهرمانی مربوط به داستانهای ویژه کودکان را نمایش میدهد. تصویر زیر خروجی نهایی پیادهسازی شده در این بخش را نشان میدهد.
گام اول: ساخت اکتیویتی جدید
در اولین گام باید اکتیویتی جدیدی با نام SuperheroListActivity
ایجاد کرد. قطعه کد زیر این اکتیویتی جدید را برای ما ایجاد میکند.
class SuperheroListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel = ViewModelProvider(this).get(SuperheroesViewModel::class.java)
setContent {SuperheroListScreen(viewModel.superheroes)}
}
}
گام دوم: طراحی منطق کسب و کار
در ادامه از کلاس ViewModel
برای پیادهسازی منطق کسب و کار برنامه استفاده میشود. کلاس ViewModel
برای نگهداری و مدیریت دادههای مرتبط با کامپوننتهای رابط کاربری بدون وابستگی به چرخه عمر آنها کاربرد دارد. در ادامه کد مربوط به کلاس SuperheroesViewModel
قرار داده شده است.
class SuperheroesViewModel : ViewModel() {
val superheroes = liveData {
val superheroList = loadSuperheroes()
emit(superheroList)
}
// Added a delay of 2 seconds to emulate a network request. This method
// just sets the list of superheroes to the livedata after 2 seconds.
suspend fun loadSuperheroes(): List {
delay(2000)
return listOf(
Superhero("Iron Man", 43, "https..."),
Superhero("Hulk", 38, "https..."),
...
)
}
}
// Model class for superhero metadata
data class Superhero(
val name: String,
val age: Int,
val profileImageUrl: String
)
نمونه کد بالا، مسئولیت بارگزاری اطلاعات مورد نیاز برای ساخت لیست شخصیتهای ابر قهرمانی در برنامه را برعهده دارد.
گام سوم: طراحی منطق رابط کاربری
«قابلیت همکاری» (Interoperability) سیستم جدید با سیستم فعلی یکی از سوالاتی است که هنگام معرفی یک فریمورک جدید باید به آن پاسخ داده شود. یکی از نکات مثبت Jetpack Compose قابلیت همکاری آن با روش توسعه سنتی در اندروید است.
منظور از قابلیت همکاری این است که میتوان از این دو ابزار در کنار یکدیگر و بدون مشکل استفاده کرد. به عنوان مثال، کد زیر نحوه تبدیل یک شی از نوع LiveData
را با استفاده از تابع observeAsState
به متغیری از نوع State
در Jetpack Compose نشان میدهد.
@Composable
fun SuperheroListScreen(
list: LiveData>) {
val superheroes by list.observeAsState(
initial = emptyList()
)
if (superheroes.isEmpty())
{LoadingComponent()}
else {SuperheroListComponent(superheroes)}
}
در نمونه کد بالا، در صورتی که شی state
خالی باشد صفحه لودینگ و در غیر این صورت لیست شخصیتهای ابرقهرمانی نشان داده میشود. برای پیادهسازی صفحه لودینگ تابع LoadingComponent
فراخوانی میشود. در ادامه، کدهای مربوط به پیادهسازی این تابع آورده شده است.
@Composable
fun LoadingComponent() {
val alignment = CenterHorizontally
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Center,
horizontalAlignment = alignment
) {
CircularProgressIndicator(Modifier.wrapContentWidth(CenterHorizontally)
)
}
}
در صورتی خالی نبودن شی state
باید لیست شخصیتهای ابرقهرمانی نمایش داده شود. برای این منظور تابع SuperheroListComponent
پیادهسازی شده است. در ادامه، کدهای مربوط به پیادهسازی این تابع آورده شده است.
@Composable
fun SuperheroListComponent(
superheroList: List
) {
LazyColumn {
items(
items = superheroList,
itemContent = { superhero ->
Card(
shape = RoundedCornerShape(4.dp),
backgroundColor = Color.White,
modifier = Modifier
.fillParentMaxWidth()
.padding(8.dp)
) {
ImageWithTitleSubtitleComponent(
superhero.name,
"Age: ${superhero.age}",
superhero.profilePictureUrl!!
)
}
}
)
}
}
تصویر زیر خروجی نهایی مربوط به پیادهسازی این صفحه از رابط کاربری اپلیکیشن را نشان میدهد.
سوالات متداول در Jetpack Compose
تا این قسمت از نوشته مفاهیم، ساختارها و کاربردهای اصلی Jetpack Compose مورد بررسی قرار گرفت. در ادامه، به پرتکرارترین سوالات این حوزه پاسخ داده خواهد شد.
نسخه API مناسب برای اجرای Jetpack Compose چیست ؟
کاتلین تنها زبان قابل استفاده در Jetpack Compose است، به دلیل این که کلاسهای موجود در Jetpack Compose با زبان برنامه نویسی کاتلین نوشته شدهاند. علاوه بر این برای کار کردن با Jetpack Compose به حداقل نسخه ۲۱ یا بالاتر از API اندروید نیاز است.
آیا برنامههای ساخته شده با Jetpack Compose سریع تر هستند؟
پارامترهای بسیاری برای سنجش سرعت و عملکرد Jetpack Compose در قیاس با رویکرد سنتی توسعه رابط کاربری اندروید با کدهای XML وجود دارد. در بسیاری از این بخشها Jetpack Compose از سرعت بالاتری برخوردار است.
آیا Jetpack Compose ابزار توسعه چند پلتفرمی محسوب میشود؟
Jetpack Compose در ابتدا برای توسعه رابط کاربری اپلیکیشنهای اندرویدی توسعه یافت. در ادامه با توجه به وجود کامپایلرهای زبان کاتلین و ابزار Compose Multiplatform امکان توسعه رابط کاربری برای وب و دسکتاپ نیز به آن اضافه شد.
مقایسه Xamarin ،React Native و Flutter برای توسعه چند پلتفرمی — راهنمای کاربردی
Jetpack Compose چیست، کتابخانه یا فریمورک؟
این ابزار راهحلی برای جلوگیری از پیچیدگیهای موجود در توسعه رابط کاربری اندروید ارائه کرده است. Jetpack Compose به زبان ساده به عنوان یک فریمورک توسعه رابط کاربری با رویکرد برنامه نویسی اعلانی شناخته میشود.
جمعبندی
پیدایش و ظهور Jetpack Compose اتفاق بسیار مهمی در بحث طراحی رابط کاربری اپلیکیشنهای اندرویدی محسوب میشود. این ابزار مدرن جایگزین بسیار خوبی برای کیت توسعه قدیمی رابط کاربری اندروید بوده است و توانسته رضایت حداکثری توسعهدهندگان اپلیکیشنهای اندرویدی را به دست آورد. توسعه رابط کاربری اپلیکیشنهای اندرویدی به کمک Jetpack Compose سادهتر، سریعتر و لذت بخشتر است و علاوه بر این، نیازی به نوشتن کدهای زیاد برای این منظور نیست.
تغییرات رخ داده بعد از ظهور Jetpack Compose به قدری عظیم است که میتوان دنیای طراحی رابط کاربری اندروید را به دو بخش قبل از پیدایش Jetpack Compose و بعد از پیدایش آن تقسیم کرد. بر همین اساس، در این نوشته سعی شد تا به این سوال پاسخ داده شود که Jetpack Compose چیست و چه کاربردهایی دارد. علاوه بر این، ضمن بررسی ساختار Jetpack Compose به سوالات متداولی همچون مزایا و معایب Jetpack Compose چیست و چرا باید از این ابزار مدرن استفاده کرد نیز پاسخ داده شد. در انتها نیز ضمن پاسخ به این سوال که پیش نیاز یادگیری Jetpack Compose چیست به صورت پروژه محور به آموزش نصب و استفاده از Jetpack Compose در پروژههای اندرویدی پرداخته شد.