Jetpack Compose پیاده سازی Material Design را ارائه می دهد، یک سیستم طراحی جامع برای ایجاد رابط های دیجیتال. اجزای طراحی متریال (دکمهها، کارتها، سوئیچها و غیره) بر روی Material Theming ساخته شدهاند، که روشی سیستماتیک برای سفارشیسازی متریال دیزاین است تا برند محصول شما را بهتر منعکس کند. یک تم متریال شامل ویژگیهای رنگ ، تایپوگرافی و شکل است. وقتی این ویژگی ها را سفارشی می کنید، تغییرات شما به طور خودکار در مؤلفه هایی که برای ساختن برنامه خود استفاده می کنید منعکس می شود.
Jetpack Compose این مفاهیم را با MaterialTheme
composable پیاده سازی می کند:
MaterialTheme( colors = // ... typography = // ... shapes = // ... ) { // app content }
پارامترهایی را که به MaterialTheme
میدهید تا برنامهتان را قالببندی کنید، پیکربندی کنید.
شکل 1. تصویر اول برنامهای را نشان میدهد که MaterialTheme
پیکربندی نمیکند، و بنابراین از استایل پیشفرض استفاده میکند. اسکرین شات دوم برنامه ای را نشان می دهد که پارامترهایی را به MaterialTheme
برای سفارشی کردن استایل ارسال می کند.
رنگ
رنگها در Compose با کلاس Color
مدلسازی میشوند، یک کلاس ساده نگهدارنده داده.
val Red = Color(0xffff0000) val Blue = Color(red = 0f, green = 0f, blue = 1f)
در حالی که میتوانید آنها را هر طور که دوست دارید سازماندهی کنید (به عنوان ثابتهای سطح بالا، در یک تکتن یا درون خطی تعریفشده)، ما قویاً توصیه میکنیم رنگها را در موضوع خود مشخص کنید و رنگها را از آنجا بازیابی کنید. این رویکرد امکان پشتیبانی آسان از تم تیره و تم های تودرتو را فراهم می کند.
شکل 2. سیستم رنگ مواد.
Compose کلاس Colors
را برای مدلسازی سیستم رنگ Material ارائه میکند. Colors
توابع سازنده را برای ایجاد مجموعه ای از رنگ های روشن یا تیره فراهم می کند:
private val Yellow200 = Color(0xffffeb46) private val Blue200 = Color(0xff91a4fc) // ... private val DarkColors = darkColors( primary = Yellow200, secondary = Blue200, // ... ) private val LightColors = lightColors( primary = Yellow500, primaryVariant = Yellow400, secondary = Blue700, // ... )
هنگامی که Colors
خود را مشخص کردید، می توانید آنها را به MaterialTheme
منتقل کنید:
MaterialTheme( colors = if (darkTheme) DarkColors else LightColors ) { // app content }
استفاده از رنگ های تم
با استفاده از MaterialTheme.colors
می توانید Colors
ارائه شده به MaterialTheme
قابل ترکیب را بازیابی کنید.
Text( text = "Hello theming", color = MaterialTheme.colors.primary )
رنگ سطح و محتوا
بسیاری از مؤلفه ها یک جفت رنگ و رنگ محتوا را می پذیرند:
Surface( color = MaterialTheme.colors.surface, contentColor = contentColorFor(color), // ... ) { /* ... */ } TopAppBar( backgroundColor = MaterialTheme.colors.primarySurface, contentColor = contentColorFor(backgroundColor), // ... ) { /* ... */ }
این به شما امکان میدهد نه تنها رنگ یک کامپوزیشن را تنظیم کنید، بلکه یک رنگ پیشفرض برای محتوا، ترکیببندیهای موجود در آن نیز ارائه کنید. بسیاری از composable ها به طور پیش فرض از این رنگ محتوا استفاده می کنند. به عنوان مثال، Text
رنگ خود را بر اساس رنگ محتوای والد خود قرار می دهد و Icon
از آن رنگ برای تنظیم رنگ خود استفاده می کند.
شکل 3. تنظیم رنگ های مختلف پس زمینه، رنگ های متن و نماد متفاوتی را تولید می کند.
متد contentColorFor()
رنگ «روشن» مناسب را برای هر رنگ تم بازیابی می کند. برای مثال، اگر یک رنگ پسزمینه primary
را روی Surface
تنظیم کنید، از این تابع برای تنظیم onPrimary
به عنوان رنگ محتوا استفاده میکند. اگر رنگ پسزمینه غیر موضوعی تنظیم میکنید، باید رنگ محتوای مناسب را نیز مشخص کنید. از LocalContentColor
برای بازیابی رنگ محتوای ترجیحی برای پسزمینه فعلی، در یک موقعیت معین در سلسله مراتب استفاده کنید.
آلفای محتوا
اغلب می خواهید میزان تاکید بر محتوا را تغییر دهید تا اهمیت ارتباط برقرار کنید و سلسله مراتب بصری ارائه دهید. توصیههای خوانایی متن طراحی متریال به استفاده از سطوح مختلف کدورت برای انتقال سطوح اهمیت مختلف توصیه میکند.
Jetpack Compose این را از طریق LocalContentAlpha
پیاده سازی می کند. با ارائه یک مقدار برای این CompositionLocal
می توانید یک آلفای محتوا را برای یک سلسله مراتب مشخص کنید. ترکیبپذیرهای تودرتو میتوانند از این مقدار برای اعمال درمان آلفا به محتوای خود استفاده کنند. برای مثال، Text
و Icon
به طور پیشفرض از ترکیب LocalContentColor
استفاده میکنند که برای استفاده از LocalContentAlpha
تنظیم شده است. مواد برخی از مقادیر آلفای استاندارد ( high
، medium
، disabled
) را مشخص میکند که توسط شی ContentAlpha
مدلسازی میشوند.
// By default, both Icon & Text use the combination of LocalContentColor & // LocalContentAlpha. De-emphasize content by setting content alpha CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) { Text( // ... ) } CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) { Icon( // ... ) Text( // ... ) }
برای کسب اطلاعات بیشتر در مورد CompositionLocal
، داده های محدوده محلی را با راهنمای CompositionLocal بررسی کنید.
شکل 4. سطوح مختلف تاکید را بر روی متن اعمال کنید تا به صورت بصری سلسله مراتب اطلاعات را منتقل کنید. خط اول متن عنوان است و دارای مهمترین اطلاعات است و بنابراین از ContentAlpha.high
استفاده می کند. خط دوم حاوی ابرداده های کم اهمیت است و بنابراین از ContentAlpha.medium
استفاده می کند.
تم تاریک
در Compose، تم های روشن و تیره را با ارائه مجموعه های مختلف Colors
به MaterialTheme
قابل ترکیب پیاده سازی می کنید:
@Composable fun MyTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { MaterialTheme( colors = if (darkTheme) DarkColors else LightColors, /*...*/ content = content ) }
در این مثال، MaterialTheme
در تابع کامپوزیشن خود پیچیده شده است، که پارامتری را می پذیرد که مشخص می کند آیا از یک تم تیره استفاده شود یا خیر. در این حالت، تابع با جستجو در تنظیمات تم دستگاه، مقدار پیشفرض darkTheme
را دریافت میکند.
برای بررسی روشن یا تیره بودن Colors
فعلی می توانید از کدی مانند این استفاده کنید:
val isLightTheme = MaterialTheme.colors.isLight Icon( painterResource( id = if (isLightTheme) { R.drawable.ic_sun_24 } else { R.drawable.ic_moon_24 } ), contentDescription = "Theme" )
پوشش های ارتفاعی
در متریال، سطوح دارای تمهای تیره با ارتفاع بالاتر، پوششهای ارتفاعی دریافت میکنند که پسزمینه آنها را روشن میکند. هر چه ارتفاع یک سطح بیشتر باشد (آن را به منبع نور ضمنی نزدیکتر می کند)، آن سطح سبک تر می شود.
این پوششها بهطور خودکار توسط Surface
Composable هنگام استفاده از رنگهای تیره و برای هر ماده دیگری که از یک سطح استفاده میکند اعمال میشود:
Surface( elevation = 2.dp, color = MaterialTheme.colors.surface, // color will be adjusted for elevation /*...*/ ) { /*...*/ }
شکل 5. کارت ها و ناوبری پایین هر دو از رنگ surface
به عنوان پس زمینه استفاده می کنند. از آنجایی که کارتها و پیمایش پایین در سطوح مختلف ارتفاع بالاتر از پسزمینه قرار دارند، رنگهای کمی متفاوت دارند – کارتها از پسزمینه روشنتر هستند و ناوبری پایینتر از کارتها روشنتر است.
برای سناریوهای سفارشی که شامل Surface
نمیشوند، از LocalElevationOverlay
استفاده کنید، یک CompositionLocal
حاوی ElevationOverlay
که توسط اجزای Surface
استفاده میشود:
// Elevation overlays // Implemented in Surface (and any components that use it) val color = MaterialTheme.colors.surface val elevation = 4.dp val overlaidColor = LocalElevationOverlay.current?.apply( color, elevation )
برای غیرفعال کردن همپوشانی ارتفاع، در یک سلسله مراتب قابل ترکیب، null
در نقطه دلخواه ارائه کنید:
MyTheme { CompositionLocalProvider(LocalElevationOverlay provides null) { // Content without elevation overlays } }
لهجه های رنگی محدود
متریال استفاده از لهجه های رنگی محدود را برای تم های تیره با ترجیح استفاده از رنگ surface
بر رنگ primary
در بیشتر موارد توصیه می کند. مواد قابل ترکیب مانند TopAppBar
و BottomNavigation
این رفتار را به طور پیش فرض پیاده سازی می کنند.
شکل 6. تم تیره متریال با لهجه های رنگی محدود. نوار برنامه بالا از رنگ اصلی در طرح زمینه روشن و رنگ سطح در تم تیره استفاده می کند.
برای سناریوهای سفارشی، از ویژگی افزونه primarySurface
استفاده کنید:
Surface( // Switches between primary in light theme and surface in dark theme color = MaterialTheme.colors.primarySurface, /*...*/ ) { /*...*/ }
تایپوگرافی
متریال یک سیستم نوع را تعریف میکند و شما را تشویق میکند که از تعداد کمی از سبکهای با نام معنایی استفاده کنید.
شکل 7. سیستم نوع مواد.
Compose سیستم نوع را با کلاسهای Typography
، TextStyle
و مربوط به فونت پیادهسازی میکند. سازنده Typography
پیشفرضهایی را برای هر سبک ارائه میکند، بنابراین میتوانید هر کدام را که نمیخواهید سفارشی کنید حذف کنید:
val raleway = FontFamily( Font(R.font.raleway_regular), Font(R.font.raleway_medium, FontWeight.W500), Font(R.font.raleway_semibold, FontWeight.SemiBold) ) val myTypography = Typography( h1 = TextStyle( fontFamily = raleway, fontWeight = FontWeight.W300, fontSize = 96.sp ), body1 = TextStyle( fontFamily = raleway, fontWeight = FontWeight.W600, fontSize = 16.sp ) /*...*/ ) MaterialTheme(typography = myTypography, /*...*/) { /*...*/ }
اگر می خواهید از همان تایپ فیس در سرتاسر استفاده کنید، defaultFontFamily parameter
را مشخص کنید و fontFamily
هر عنصر TextStyle
را حذف کنید:
val typography = Typography(defaultFontFamily = raleway) MaterialTheme(typography = typography, /*...*/) { /*...*/ }
استفاده از سبک های متن
TextStyle
از طریق MaterialTheme.typography
قابل دسترسی است. بازیابی TextStyle
به این صورت:
Text( text = "Subtitle2 styled", style = MaterialTheme.typography.subtitle2 )
شکل 8. از مجموعه ای از حروف و سبک ها برای بیان نام تجاری خود استفاده کنید.
شکل
متریال یک سیستم شکل را تعریف می کند و به شما این امکان را می دهد که اشکال را برای اجزای بزرگ، متوسط و کوچک تعریف کنید.
شکل 9. سیستم شکل مواد.
Compose سیستم شکل را با کلاس Shapes
پیادهسازی میکند که به شما امکان میدهد برای هر دسته اندازه یک CornerBasedShape
مشخص کنید:
val shapes = Shapes( small = RoundedCornerShape(percent = 50), medium = RoundedCornerShape(0f), large = CutCornerShape( topStart = 16.dp, topEnd = 0.dp, bottomEnd = 0.dp, bottomStart = 16.dp ) ) MaterialTheme(shapes = shapes, /*...*/) { /*...*/ }
بسیاری از مؤلفه ها به طور پیش فرض از این اشکال استفاده می کنند. به عنوان مثال، Button
، TextField
، و FloatingActionButton
به طور پیشفرض روی کوچک، AlertDialog
پیشفرض متوسط، و ModalDrawer
پیشفرض روی بزرگ است - برای نقشهبرداری کامل ، مرجع طرح شکل را ببینید.
استفاده از اشکال
Shape
s از طریق MaterialTheme.shapes
قابل دسترسی است. Shape
s را با کد زیر بازیابی کنید:
Surface( shape = MaterialTheme.shapes.medium, /*...*/ ) { /*...*/ }
شکل 10. از اشکال برای بیان برند یا حالت استفاده کنید.
سبک های پیش فرض
هیچ مفهومی معادل در Compose of styles default from Android Views وجود ندارد. شما می توانید عملکرد مشابهی را با ایجاد توابع کامپوزیشن "overload" خود که اجزای Material را می پوشانند، ارائه دهید. به عنوان مثال، برای ایجاد سبکی از دکمه، یک دکمه را در تابع قابل ترکیب خود بپیچید، مستقیماً پارامترهایی را که میخواهید تغییر دهید تنظیم کنید، و دیگران را به عنوان پارامتر در معرض ترکیبپذیر قرار دهید.
@Composable fun MyButton( onClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Button( colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.secondary ), onClick = onClick, modifier = modifier, content = content ) }
همپوشانی تم
میتوانید با تودرتو کردن مواد Composable MaterialTheme
، به معادل همپوشانیهای تم از Android Views در Compose دست پیدا کنید. از آنجایی که MaterialTheme
رنگها، تایپوگرافی و اشکال را به مقدار تم فعلی پیشفرض میکند، اگر یک تم فقط یکی از آن پارامترها را تنظیم کند، پارامترهای دیگر مقادیر پیشفرض خود را حفظ میکنند.
علاوه بر این، هنگام انتقال صفحات مبتنی بر View به Compose، مراقب استفاده از ویژگی android:theme
باشید. به احتمال زیاد شما به یک MaterialTheme
جدید در آن قسمت از درخت Compose UI نیاز دارید.
در این مثال، صفحه جزئیات از PinkTheme
برای بیشتر صفحه و سپس BlueTheme
برای بخش مربوطه استفاده می کند. اسکرین شات و کد زیر را ببینید.
شکل 11. تم های تو در تو.
@Composable fun DetailsScreen(/* ... */) { PinkTheme { // other content RelatedSection() } } @Composable fun RelatedSection(/* ... */) { BlueTheme { // content } }
حالت های جزء
اجزای موادی که می توان با آنها تعامل کرد (کلیک کرد، تغییر داد و غیره) می تواند در حالت های بصری مختلف باشد. حالت ها شامل فعال، غیرفعال، فشرده و غیره است.
Composable ها اغلب یک پارامتر enabled
دارند. تنظیم آن بر روی false
از تعامل جلوگیری می کند و ویژگی هایی مانند رنگ و ارتفاع را تغییر می دهد تا حالت جزء را به صورت بصری منتقل کند.
شکل 12. دکمه با enabled = true
(سمت چپ) و enabled = false
(راست).
در بیشتر موارد می توانید برای مقادیری مانند رنگ و ارتفاع به پیش فرض ها تکیه کنید. اگر بخواهید مقادیر مورد استفاده در حالت های مختلف را پیکربندی کنید، کلاس ها و توابع راحتی در دسترس هستند. نمونه دکمه زیر را ببینید:
Button( onClick = { /* ... */ }, enabled = true, // Custom colors for different states colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.secondary, disabledBackgroundColor = MaterialTheme.colors.onBackground .copy(alpha = 0.2f) .compositeOver(MaterialTheme.colors.background) // Also contentColor and disabledContentColor ), // Custom elevation for different states elevation = ButtonDefaults.elevation( defaultElevation = 8.dp, disabledElevation = 2.dp, // Also pressedElevation ) ) { /* ... */ }
شکل 13. دکمه با enabled = true
(چپ) و enabled = false
(راست)، با مقادیر رنگ و ارتفاع تنظیم شده.
امواج
اجزای مواد از امواج برای نشان دادن تعامل با آنها استفاده می کنند. اگر از MaterialTheme
در سلسله مراتب خود استفاده میکنید، یک Ripple
به عنوان Indication
پیشفرض در اصلاحکنندههایی مانند clickable
و indication
استفاده میشود.
در بیشتر موارد می توانید به Ripple
پیش فرض تکیه کنید. اگر می خواهید ظاهر آنها را پیکربندی کنید، می توانید از RippleTheme
برای تغییر ویژگی هایی مانند رنگ و آلفا استفاده کنید.
می توانید RippleTheme
گسترش دهید و از توابع ابزار defaultRippleColor
و defaultRippleAlpha
استفاده کنید. سپس می توانید با استفاده از LocalRippleTheme
تم ریپل سفارشی خود را در سلسله مراتب خود ارائه دهید:
@Composable fun MyApp() { MaterialTheme { CompositionLocalProvider( LocalRippleTheme provides SecondaryRippleTheme ) { // App content } } } @Immutable private object SecondaryRippleTheme : RippleTheme { @Composable override fun defaultColor() = RippleTheme.defaultRippleColor( contentColor = MaterialTheme.colors.secondary, lightTheme = MaterialTheme.colors.isLight ) @Composable override fun rippleAlpha() = RippleTheme.defaultRippleAlpha( contentColor = MaterialTheme.colors.secondary, lightTheme = MaterialTheme.colors.isLight ) }
شکل 14. دکمه هایی با مقادیر ریپل متفاوت از طریق RippleTheme
ارائه شده است.
بیشتر بدانید
برای کسب اطلاعات بیشتر در مورد Material Theming در Compose، به منابع اضافی زیر مراجعه کنید.
Codelabs
ویدیوها
{% کلمه به کلمه %}برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- سیستم های طراحی سفارشی در Compose
- از Material 2 به Material 3 در Compose مهاجرت کنید
- قابلیت دسترسی در نوشتن