جتپک کامپوز (Jetpack Compose) طراحی و ساخت رابط کاربری (UI) برنامه شما را بسیار آسانتر میکند. کامپوز حالت (state) را از طریق موارد زیر به عناصر رابط کاربری تبدیل میکند:
- ترکیب عناصر
- طرحبندی عناصر
- ترسیم عناصر
این سند بر روی چیدمان عناصر تمرکز دارد و برخی از بلوکهای سازندهای که Compose برای کمک به شما در چیدمان عناصر رابط کاربری ارائه میدهد را توضیح میدهد.
اهداف طرحبندیها در Compose
پیادهسازی سیستم طرحبندی Jetpack Compose دو هدف اصلی دارد:
- عملکرد بالا
- امکان نوشتن آسان طرحبندیهای سفارشی
مبانی توابع قابل ترکیب
توابع قابل ترکیب، بلوک سازندهی اصلی Compose هستند. یک تابع قابل ترکیب، Unit است که بخشی از رابط کاربری شما را توصیف میکند. این تابع مقداری ورودی میگیرد و آنچه را که روی صفحه نمایش داده میشود، تولید میکند. برای اطلاعات بیشتر در مورد توابع قابل ترکیب، به مستندات مدل ذهنی Compose نگاهی بیندازید.
یک تابع composable ممکن است چندین عنصر رابط کاربری را منتشر کند. با این حال، اگر در مورد نحوه چیدمان آنها راهنمایی ارائه ندهید، Compose ممکن است عناصر را به روشی که شما دوست ندارید، مرتب کند. برای مثال، این کد دو عنصر متنی تولید میکند:
@Composable fun ArtistCard() { Text("Alfred Sisley") Text("3 minutes ago") }
بدون راهنمایی در مورد نحوه چیدمان آنها، Compose عناصر متن را روی هم قرار میدهد و آنها را غیرقابل خواندن میکند:

Compose مجموعهای از طرحبندیهای آماده برای کمک به شما در چیدمان عناصر رابط کاربری ارائه میدهد و تعریف طرحبندیهای تخصصیتر خودتان را آسان میکند.
اجزای طرحبندی استاندارد
در بسیاری از موارد، میتوانید فقط از عناصر طرحبندی استاندارد Compose استفاده کنید.
Column برای قرار دادن موارد به صورت عمودی روی صفحه استفاده کنید.
@Composable fun ArtistCardColumn() { Column { Text("Alfred Sisley") Text("3 minutes ago") } }

به طور مشابه، از Row برای قرار دادن آیتمها به صورت افقی روی صفحه استفاده کنید. هر دو Column و Row از پیکربندی ترازبندی عناصری که در خود جای میدهند پشتیبانی میکنند.
@Composable fun ArtistCardRow(artist: Artist) { Row(verticalAlignment = Alignment.CenterVertically) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { Text(artist.name) Text(artist.lastSeenOnline) } } }

از Box برای قرار دادن عناصر روی یکدیگر استفاده کنید. Box همچنین از پیکربندی ترازبندی خاص عناصر موجود در خود پشتیبانی میکند.
@Composable fun ArtistAvatar(artist: Artist) { Box { Image(bitmap = artist.image, contentDescription = "Artist image") Icon(Icons.Filled.Check, contentDescription = "Check mark") } }

اغلب این بلوکهای سازنده تنها چیزی هستند که نیاز دارید. میتوانید تابع قابل ترکیب خودتان را بنویسید تا این طرحبندیها را در یک طرحبندی پیچیدهتر که مناسب برنامه شماست، ترکیب کند.
برای تنظیم موقعیت فرزندان در یک Row ، آرگومانهای horizontalArrangement و verticalAlignment را تنظیم کنید. برای یک Column ، آرگومانهای verticalArrangement و horizontalAlignment را تنظیم کنید:
@Composable fun ArtistCardArrangement(artist: Artist) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End ) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { /*...*/ } } }

مدل چیدمان
در مدل طرحبندی، درخت رابط کاربری در یک مرحله طرحبندی میشود. ابتدا از هر گره خواسته میشود که خودش را اندازهگیری کند، سپس هر فرزند را به صورت بازگشتی اندازهگیری میکند و محدودیتهای اندازه را به پایین درخت به فرزندان منتقل میکند. سپس، گرههای برگ اندازهگذاری و قرار داده میشوند، و اندازهها و دستورالعملهای قرارگیری تعیینشده به بالای درخت ارسال میشوند.
به طور خلاصه، والدین قبل از فرزندانشان اندازه میگیرند، اما بعد از فرزندانشان سایزبندی و قرار داده میشوند.
تابع SearchResult زیر را در نظر بگیرید.
@Composable fun SearchResult() { Row { Image( // ... ) Column { Text( // ... ) Text( // ... ) } } }
این تابع، درخت رابط کاربری زیر را تولید میکند.
SearchResult
Row
Image
Column
Text
Text
در مثال SearchResult ، طرح درختی رابط کاربری از این ترتیب پیروی میکند:
- از
Rowگره ریشه خواسته میشود که اندازهگیری کند. - گره ریشه
Rowاز اولین فرزندش،Image، میخواهد که اندازهگیری کند. -
Imageیک گره برگ است (یعنی فرزندی ندارد)، بنابراین اندازه را گزارش میدهد و دستورالعملهای قرارگیری را برمیگرداند. - گره ریشه
Rowاز فرزند دوم خود،Column، میخواهد که اندازهگیری کند. - گره
Columnاز اولین فرزندTextخود میخواهد که اندازهگیری کند. - اولین گره
Textیک گره برگ است، بنابراین اندازه را گزارش میدهد و دستورالعملهای قرارگیری را برمیگرداند. - گره
Columnاز فرزند دومTextخود میخواهد که اندازهگیری کند. - گره
Textدوم یک گره برگ است، بنابراین اندازه را گزارش میدهد و دستورالعملهای قرارگیری را برمیگرداند. - اکنون که گره
Column، فرزندان خود را اندازهگیری، تعیین اندازه و قرار داده است، میتواند اندازه و محل قرارگیری خود را تعیین کند. - اکنون که گره ریشه
Rowفرزندان خود را اندازهگیری، تعیین اندازه و قرار داده است، میتواند اندازه و محل قرارگیری خود را تعیین کند.
عملکرد
Compose با اندازهگیری تنها یک بار فرزندان، به عملکرد بالایی دست مییابد. اندازهگیری تکگذر برای عملکرد خوب است و به Compose اجازه میدهد تا به طور موثر درختهای رابط کاربری عمیق را مدیریت کند. اگر یک عنصر فرزند خود را دو بار اندازهگیری کند و آن فرزند هر یک از فرزندان خود را دو بار و به همین ترتیب، یک تلاش واحد برای طرحبندی کل رابط کاربری باید کار زیادی انجام دهد، که حفظ عملکرد برنامه شما را دشوار میکند.
اگر طرحبندی شما به دلایلی به چندین اندازهگیری نیاز دارد، Compose یک سیستم ویژه به نام اندازهگیریهای ذاتی ارائه میدهد. میتوانید اطلاعات بیشتر در مورد این ویژگی را در بخش اندازهگیریهای ذاتی در طرحبندیهای Compose مطالعه کنید.
از آنجایی که اندازهگیری و جایگذاری، زیرمرحلههای مجزایی از مرحله طرحبندی هستند، هرگونه تغییری که فقط بر جایگذاری اقلام تأثیر بگذارد، نه اندازهگیری، میتواند جداگانه اجرا شود.
استفاده از اصلاحکنندهها در طرحبندیهایتان
همانطور که در بخش «اصلاحکنندههای ترکیب» بحث شد، میتوانید از اصلاحکنندهها برای تزئین یا تقویت ترکیبپذیرهای خود استفاده کنید. اصلاحکنندهها برای سفارشیسازی طرحبندی شما ضروری هستند. برای مثال، در اینجا ما چندین اصلاحکننده را برای سفارشیسازی ArtistCard به هم متصل میکنیم:
@Composable fun ArtistCardModifiers( artist: Artist, onClick: () -> Unit ) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { Row(verticalAlignment = Alignment.CenterVertically) { /*...*/ } Spacer(Modifier.size(padding)) Card( elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), ) { /*...*/ } } }

در کد بالا، به توابع اصلاحکنندهی مختلفی که با هم استفاده شدهاند، توجه کنید.
-
clickableباعث میشود که یک composable به ورودی کاربر واکنش نشان دهد و یک موج نشان دهد. -
paddingاطراف یک عنصر فاصله ایجاد میکند. -
fillMaxWidthباعث میشود که عنصر قابل ترکیب، حداکثر عرضی را که از والدش دریافت میکند، داشته باشد. -
size()عرض و ارتفاع ترجیحی یک عنصر را مشخص میکند.
طرحبندیهای قابل اسکرول
برای اطلاعات بیشتر در مورد طرحبندیهای قابل اسکرول، به مستندات ژستهای نوشتن (Compose gestures) مراجعه کنید.
برای لیستها و لیستهای تنبل، مستندات Compose lists را بررسی کنید.
طرحبندیهای واکنشگرا
یک طرحبندی باید با در نظر گرفتن جهتگیریهای مختلف صفحه نمایش و اندازههای مختلف فرم فاکتور طراحی شود. Compose چندین مکانیزم را به صورت پیشفرض ارائه میدهد تا تطبیق طرحبندیهای قابل ترکیب شما با پیکربندیهای مختلف صفحه نمایش را تسهیل کند.
محدودیتها
برای اینکه محدودیتهایی که از والد میآیند را بشناسید و طرحبندی را بر اساس آنها طراحی کنید، میتوانید از BoxWithConstraints استفاده کنید. محدودیتهای اندازهگیری را میتوانید در محدودهی content lambda پیدا کنید. میتوانید از این محدودیتهای اندازهگیری برای ایجاد طرحبندیهای مختلف برای پیکربندیهای مختلف صفحه نمایش استفاده کنید:
@Composable fun WithConstraintsComposable() { BoxWithConstraints { Text("My minHeight is $minHeight while my maxWidth is $maxWidth") } }
طرحبندیهای مبتنی بر اسلات
Compose طیف وسیعی از composableها را بر اساس طراحی متریال با وابستگی androidx.compose.material:material (که هنگام ایجاد یک پروژه Compose در اندروید استودیو گنجانده شده است) ارائه میدهد تا ساخت رابط کاربری آسان شود. عناصری مانند Drawer ، FloatingActionButton و TopAppBar همگی ارائه شدهاند.
کامپوننتهای متریال از APIهای اسلات (slot APIs) به شدت استفاده میکنند، الگویی که Compose برای ایجاد لایهای از سفارشیسازی بر روی composableها معرفی میکند. این رویکرد کامپوننتها را انعطافپذیرتر میکند، زیرا آنها یک عنصر فرزند را میپذیرند که میتواند خودش را پیکربندی کند، به جای اینکه مجبور باشد هر پارامتر پیکربندی فرزند را نمایش دهد. اسلاتها یک فضای خالی در رابط کاربری باقی میگذارند تا توسعهدهنده بتواند آن را به دلخواه پر کند. به عنوان مثال، اینها اسلاتهایی هستند که میتوانید در TopAppBar سفارشی کنید:

Composableها معمولاً یک lambda با قابلیت ترکیب content ( content: @Composable () -> Unit ) میگیرند. APIهای اسلات چندین پارامتر content را برای کاربردهای خاص ارائه میدهند. برای مثال، TopAppBar به شما امکان میدهد محتوای title ، navigationIcon و actions را ارائه دهید.
برای مثال، Scaffold به شما امکان میدهد یک رابط کاربری (UI) را با ساختار چیدمان اولیه Material Design پیادهسازی کنید. Scaffold اسلاتهایی را برای رایجترین کامپوننتهای سطح بالای Material مانند TopAppBar ، BottomAppBar ، FloatingActionButton و Drawer فراهم میکند. با استفاده از Scaffold ، میتوان به راحتی مطمئن شد که این کامپوننتها به درستی در موقعیت مناسب قرار گرفتهاند و به درستی با هم کار میکنند.

@Composable fun HomeScreen(/*...*/) { ModalNavigationDrawer(drawerContent = { /* ... */ }) { Scaffold( topBar = { /*...*/ } ) { contentPadding -> // ... } } }
برای شما توصیه میشود
- توجه: متن لینک زمانی نمایش داده میشود که جاوا اسکریپت غیرفعال باشد.
- اصلاحکنندههای ترکیب
- کاتلین برای جتپک کامپوز
- اجزای مواد و طرح بندی ها