این صفحه یک نمای کلی در سطح بالایی از لایه های معماری تشکیل دهنده Jetpack Compose و اصول اصلی که این طراحی را تشکیل می دهند ارائه می دهد.
Jetpack Compose یک پروژه یکپارچه واحد نیست. از تعدادی ماژول ساخته شده است که با هم مونتاژ می شوند تا یک پشته کامل را تشکیل دهند. درک ماژول های مختلف سازنده Jetpack Compose شما را قادر می سازد:
- از سطح مناسب انتزاع برای ساختن اپلیکیشن یا کتابخانه خود استفاده کنید
- درک کنید که چه زمانی میتوانید برای کنترل یا سفارشیسازی بیشتر، به سطح پایینتری رها شوید
- وابستگی های خود را به حداقل برسانید
لایه ها
لایه های اصلی Jetpack Compose عبارتند از:
شکل 1. لایه های اصلی Jetpack Compose.
هر لایه بر روی سطوح پایین تر ساخته شده است و عملکرد را برای ایجاد اجزای سطح بالاتر ترکیب می کند. هر لایه بر روی APIهای عمومی لایههای پایینتر ساخته میشود تا مرزهای ماژول را تأیید کند و شما را قادر میسازد تا هر لایه را در صورت نیاز جایگزین کنید. بیایید این لایه ها را از پایین به بالا بررسی کنیم.
- زمان اجرا
- این ماژول اصول زمان اجرا Compose مانند
remember
،mutableStateOf
، حاشیه نویسی@Composable
وSideEffect
را ارائه می دهد. اگر فقط به توانایی های مدیریت درخت Compose نیاز دارید، نه UI آن، می توانید مستقیماً روی این لایه ایجاد کنید. - UI
- لایه UI از چندین ماژول (
ui-text
،ui-graphics
،ui-tooling
و غیره) تشکیل شده است. این ماژولها اصول جعبه ابزار UI، مانندLayoutNode
،Modifier
، کنترلکنندههای ورودی، طرحبندیهای سفارشی و طراحی را پیادهسازی میکنند. اگر فقط به مفاهیم اساسی یک جعبه ابزار UI نیاز دارید، میتوانید روی این لایه بسازید. - بنیاد
- این ماژول بلوکهای ساختمانی آگنوستیک سیستم طراحی را برای Compose UI فراهم میکند، مانند
Row
andColumn
،LazyColumn
، تشخیص حرکات خاص، و غیره. ممکن است برای ایجاد سیستم طراحی خود، روی لایه پایه ایجاد کنید. - مواد
- این ماژول پیادهسازی سیستم طراحی متریال را برای Compose UI ارائه میکند که یک سیستم موضوعی، اجزای سبک، نشانههای موج دار، نمادها را ارائه میدهد. هنگام استفاده از طراحی متریال در برنامه خود، بر روی این لایه بسازید.
اصول طراحی
یک اصل راهنما برای Jetpack Compose این است که به جای چند جزء یکپارچه، قطعات کوچک و متمرکزی از عملکرد ارائه دهد که بتوان آنها را با هم مونتاژ کرد (یا ترکیب کرد). این رویکرد دارای تعدادی مزیت است.
کنترل کنید
اجزای سطح بالاتر تمایل دارند کارهای بیشتری برای شما انجام دهند، اما میزان کنترل مستقیمی که دارید را محدود می کنند. اگر به کنترل بیشتری نیاز دارید، میتوانید برای استفاده از یک جزء سطح پایینتر، «کم کردن» را انجام دهید.
به عنوان مثال، اگر می خواهید رنگ یک جزء را متحرک کنید، ممکن است از animateColorAsState
API استفاده کنید:
val color = animateColorAsState(if (condition) Color.Green else Color.Red)
با این حال، اگر به این کامپوننت نیاز دارید که همیشه خاکستری شروع شود، نمیتوانید با این API این کار را انجام دهید. درعوض، میتوانید برای استفاده از Animatable
API سطح پایینتر پایین بیایید:
val color = remember { Animatable(Color.Gray) } LaunchedEffect(condition) { color.animateTo(if (condition) Color.Green else Color.Red) }
سطح بالاتر animateColorAsState
API خود بر روی سطح پایین تر Animatable
API ساخته شده است. استفاده از API سطح پایین تر پیچیده تر است اما کنترل بیشتری را ارائه می دهد. سطحی از انتزاع را انتخاب کنید که به بهترین وجه با نیازهای شما مطابقت دارد.
سفارشی سازی
مونتاژ اجزای سطح بالاتر از بلوک های ساختمانی کوچکتر، سفارشی کردن اجزا را در صورت نیاز بسیار آسان تر می کند. به عنوان مثال، اجرای Button
ارائه شده توسط لایه Material را در نظر بگیرید:
@Composable fun Button( // … content: @Composable RowScope.() -> Unit ) { Surface(/* … */) { CompositionLocalProvider(/* … */) { // set LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { Row( // … content = content ) } } } }
یک Button
از 4 جزء مونتاژ شده است:
یک
Surface
مواد که پسزمینه، شکل، مدیریت کلیک و غیره را ارائه میکند.یک
CompositionLocalProvider
که وقتی دکمه فعال یا غیرفعال می شود، آلفای محتوا را تغییر می دهدیک
ProvideTextStyle
سبک متن پیش فرض را برای استفاده تنظیم می کندیک
Row
خط مشی طرح بندی پیش فرض را برای محتوای دکمه ارائه می کند
ما برخی از پارامترها و نظرات را حذف کردهایم تا ساختار را واضحتر کنیم، اما کل مؤلفه فقط حدود 40 خط کد است زیرا به سادگی این 4 مؤلفه را برای پیادهسازی دکمه جمعآوری میکند. مؤلفههایی مانند Button
در مورد پارامترهایی که در معرض نمایش قرار میدهند نظر دارند، و به این ترتیب سفارشیسازیهای رایج را در برابر انفجار پارامترهایی که میتواند استفاده از یک مؤلفه را سختتر میکند، متعادل کند. برای مثال، اجزای متریال، سفارشیسازیهای مشخصشده در سیستم طراحی متریال را ارائه میدهند و پیروی از اصول طراحی متریال را آسان میکنند.
با این حال، اگر میخواهید سفارشیسازی را فراتر از پارامترهای یک مؤلفه انجام دهید، میتوانید یک سطح را پایین بیاورید و یک مؤلفه را جدا کنید. به عنوان مثال، Material Design مشخص می کند که دکمه ها باید یک پس زمینه رنگی ثابت داشته باشند. اگر به پس زمینه گرادیان نیاز دارید، این گزینه توسط پارامترهای Button
پشتیبانی نمی شود. در این مورد می توانید از اجرای Button
Material به عنوان مرجع استفاده کنید و جزء خود را بسازید:
@Composable fun GradientButton( // … background: List<Color>, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background( Brush.horizontalGradient(background) ) ) { CompositionLocalProvider(/* … */) { // set material LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { content() } } } }
پیاده سازی فوق به استفاده از اجزای لایه Material، مانند مفاهیم آلفای محتوای فعلی و سبک متن فعلی ادامه می دهد. با این حال، متریال Surface
با یک Row
جایگزین می کند و آن را برای رسیدن به ظاهر مورد نظر سبک می کند.
اگر اصلاً نمیخواهید از مفاهیم متریال استفاده کنید، برای مثال اگر سیستم طراحی سفارشی خود را بسازید، میتوانید صرفاً از اجزای لایه پایه استفاده کنید:
@Composable fun BespokeButton( // … backgroundColor: Color, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background(backgroundColor) ) { // No Material components used content() } }
Jetpack Compose ساده ترین نام ها را برای اجزای بالاترین سطح ذخیره می کند. برای مثال، androidx.compose.material.Text
بر اساس androidx.compose.foundation.text.BasicText
ساخته شده است. این امکان را فراهم می کند تا در صورت تمایل به جایگزینی سطوح بالاتر، پیاده سازی خود را با قابل کشف ترین نام ارائه دهید.
انتخاب انتزاع درست
فلسفه Compose برای ساخت اجزای لایهای و قابل استفاده مجدد به این معنی است که همیشه نباید به بلوکهای ساختمانی سطح پایینتر برسید. بسیاری از مؤلفههای سطح بالاتر نه تنها عملکرد بیشتری را ارائه میدهند، بلکه اغلب بهترین شیوهها مانند پشتیبانی از دسترسی را اجرا میکنند.
برای مثال، اگر میخواهید پشتیبانی ژستهای حرکتی را به مؤلفه سفارشی خود اضافه کنید، میتوانید این را از ابتدا با استفاده از Modifier.pointerInput
بسازید، اما مؤلفههای سطح بالاتر دیگری نیز در بالای آن ساخته شدهاند که ممکن است نقطه شروع بهتری را ارائه دهند، برای مثال Modifier.draggable
، Modifier.scrollable
یا Modifier.swipeable
.
به عنوان یک قاعده، ترجیح میدهید بر روی مولفههای بالاترین سطحی بسازید که عملکردهای مورد نیاز شما را ارائه میدهد تا از بهترین شیوههایی که شامل میشوند بهرهمند شوید.
بیشتر بدانید
برای نمونه ای از ساختن یک سیستم طراحی سفارشی به نمونه Jetsnack مراجعه کنید.
{% کلمه به کلمه %}برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- Kotlin برای Jetpack Compose
- فهرست ها و شبکه ها
- عوارض جانبی در Compose