Material 3 Expressive تکامل بعدی «طراحی Material» است. این شامل ویژگیهای بهروزرسانیشده زمینهسازی، عناصر، و شخصیسازی مانند رنگ پویا است.
این راهنما بر انتقال از کتابخانه Jetpack Wear Compose Material 2.5 (androidx.wear.compose) به کتابخانه Jetpack Wear Compose Material 3 (androidx.wear.compose.material3) برای برنامهها تمرکز دارد.
رویکردها
برای انتقال کد برنامه از M2.5 به M3، از همان رویکردی که در راهنمای انتقال تلفن Compose Material توضیح داده شده است، بهویژه موارد زیر، پیروی کنید:
- نباید از هر دو نسخه M2.5 و M3 در یک برنامه بهصورت بلندمدت استفاده کنید.
- دیگر نباید از کتابخانههای Horologist Composables، Compose Layout، یا Compose Material استفاده کنید. بهجای آن، از عناصر M3 استفاده کنید.
- یک رویکرد مرحلهای اتخاذ کنید.
وابستگیها
M3 بسته و نسخه جداگانهای نسبتبه M2.5 دارد:
M2.5
implementation("androidx.wear.compose:compose-material:1.4.0")
M3
implementation("androidx.wear.compose:compose-material3:1.7.0")
جدیدترین نسخههای M3 را در صفحه «انتشارهای Wear Compose» ببینید.
کتابخانه Wear Compose Foundation نسخه ۱.۷.۰
چند عنصر جدید معرفی کرده است که برای کار کردن با عناصر Material 3 طراحی شدهاند.
بههمین ترتیب، SwipeDismissableNavHost از کتابخانه «پیمایش Wear Compose» هنگام اجرا در Wear OS 6 (سطح API 36) یا بالاتر، پویانمایی بهروزشدهای دارد. وقتی به نسخه Wear Compose Material 3 بهروزرسانی میکنید، پیشنهاد میکنیم کتابخانههای Wear Compose Foundation و Navigation را نیز بهروزرسانی کنید:
implementation("androidx.wear.compose:compose-foundation:1.7.0")
implementation("androidx.wear.compose:compose-navigation:1.7.0")
زمینه
در هر دو M2.5 و M3، عنصر ترکیبی زمینه MaterialTheme نامیده میشود، اما
بستههای وارداتی و پارامترها متفاوت هستند. در M3، پارامتر Colors به ColorScheme تغییر نام داده شده است و MotionScheme برای پیادهسازی انتقالها معرفی شده است.
M2.5
import androidx.wear.compose.material.MaterialTheme
MaterialTheme(
colors = AppColors,
typography = AppTypography,
shapes = AppShapes,
content = content
)
M3
import androidx.wear.compose.material3.MaterialTheme // ... MaterialTheme( colorScheme = ColorScheme(), typography = Typography(), shapes = Shapes(), motionScheme = MotionScheme.standard(), content = { /*content here*/ } )
رنگ
سیستم رنگ در M3 بهطور قابلتوجهی با M2.5 متفاوت است. تعداد پارامترهای رنگ افزایش یافته است، نامهای متفاوتی دارند، و بهطور متفاوتی به
عناصر M3 نگاشت میشوند. در «نوشتن»، این مورد برای کلاس M2.5 Colors، کلاس M3
ColorScheme، و عملکردهای مرتبط اعمال میشود:
M2.5
import androidx.wear.compose.material.Colors
val appColorScheme: Colors = Colors(
// M2.5 Color parameters
)
M3
import androidx.wear.compose.material3.ColorScheme // ... val appColorScheme: ColorScheme = ColorScheme( // M3 ColorScheme parameters )
جدول زیر تفاوتهای کلیدی بین M2.5 و M3 را شرح میدهد:
| M2.5 | M3 |
|---|---|
Colors |
نام آن به ColorScheme تغییر کرده است |
| ۱۳ رنگ | ۲۹ رنگ |
| موجود نیست | زمینهسازی رنگ پویا جدید |
| موجود نیست | رنگهای سوم جدید برای بیان بیشتر |
زمینه رنگ پویا
ویژگی جدید در M3 زمینه رنگ پویا است. اگر کاربران رنگهای صفحه ساعت را تغییر دهند، رنگهای میانای کاربر نیز تغییر میکند تا با آن مطابقت داشته باشد.
از تابع dynamicColorScheme برای پیادهسازی آرایش رنگهای پویا
و ارائه defaultColorScheme بهعنوان جایگزین درصورتیکه آرایش رنگهای پویا
دردسترس نباشد استفاده کنید.
@Composable fun myApp() { val dynamicColorScheme = dynamicColorScheme(LocalContext.current) MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {} } internal val myBrandColors: ColorScheme = ColorScheme( /* Specify colors here */)
نویسهنگاری
سیستم حروفچینی در M3 با M2.5 متفاوت است و شامل ویژگیهای زیر است:
- نه سبک نوشتار جدید
- قلمهای انعطافپذیر که امکان سفارشیسازی مقیاسهای نوع را برای وزنها، پهنا، و گردیهای مختلف فراهم میکنند
AnimatedTextکه از قلمهای انعطافپذیر استفاده میکند
M2.5
import androidx.wear.compose.material.Typography
val Typography = Typography(
// M2.5 TextStyle parameters
)
M3
import androidx.wear.compose.material3.Typography val Typography = Typography( // M3 TextStyle parameters )
قلمهای انعطافپذیر
«قلمهای انعطافپذیر» به طراحان امکان میدهد پهنا و وزن نوع را برای اندازههای خاص مشخص کنند.
سبکهای نوشتار
سبکهای نوشتاری زیر در M3 دردسترس است. اینها بهطور پیشفرض توسط اجزای مختلف M3 بهکار گرفته میشوند.
| نویسهنگاری | سبک نوشتار |
|---|---|
| نمایش | displayLarge، displayMedium، displaySmall |
| عنوان | titleLarge، titleMedium، titleSmall |
| برچسب | labelLarge، labelMedium، labelSmall |
| بدن | bodyLarge، bodyMedium، bodySmall، bodyExtraSmall |
| عدد | numeralExtraLarge، numeralLarge، numeralMedium، numeralSmall، numeralExtraSmall |
| کمان | arcLarge، arcMedium، arcSmall |
شکلها
سیستم شکل در M3 با M2.5 متفاوت است. تعداد پارامترهای شکل افزایش یافته است، نامهای متفاوتی دارند، و بهصورت متفاوتی به عناصر M3 نگاشت میشوند. اندازههای شکل زیر دردسترس است:
- بسیار کوچک
- کوچک
- متوسط
- بزرگ
- بسیار بزرگ
در «نوشتن»، این مورد برای کلاس M2.5 Shapes و کلاس M3
Shapes اعمال میشود:
M2.5
import androidx.wear.compose.material.Shapes
val Shapes = Shapes(
// M2.5 Shapes parameters
)
M3
import androidx.wear.compose.material3.Shapes val Shapes = Shapes( // M3 Shapes parameters )
از نگاشت پارامتر «اشکال» از انتقال از Material 2 به Material 3 در Compose بهعنوان نقطه شروع استفاده کنید.
تغییر تدریجی شکل
M3 «تغییر شکل» را معرفی میکند: اکنون شکلها در پاسخ به تعاملات تغییر میکنند.
رفتار «تغییر شکل» بهعنوان تنوعی در تعدادی از دکمههای گرد دردسترس است، فهرست زیر دکمههایی را نشان میدهد که از «تغییر شکل» پشتیبانی میکنند:
| دکمهها | عملکرد تغییر شکل |
|---|---|
IconButton |
IconButtonDefaults.animatedShapes دکمه نماد را هنگام فشار دادن پویانمایی میکند |
IconToggleButton |
IconToggleButtonDefaults.animatedShapes دکمه روشن/خاموش نماد را هنگام فشار دادن پویانمایی میکند و IconToggleButtonDefaults.variantAnimatedShapes دکمه روشن/خاموش نماد را هنگام فشار دادن و علامت زدن/برداشتن علامت پویانمایی میکند |
TextButton |
TextButtonDefaults.animatedShapes دکمه نوشتاری را هنگام فشار دادن پویانمایی میکند |
TextToggleButton |
TextToggleButtonDefaults.animatedShapes کلید تغییر نوشتار را هنگام فشار دادن پویانمایی میکند و TextToggleButtonDefaults.variantAnimatedShapes کلید تغییر نوشتار را هنگام فشار دادن و علامت زدن/برداشتن علامت پویانمایی میکند |
عناصر و چیدمان
اکثر عناصر و چیدمانهای M2.5 در M3 دردسترس است. بااینحال، برخیاز چیدمانها و عناصر M3 در M2.5 وجود نداشتند. علاوهبراین، برخیاز عناصر M3 تنوع بیشتری نسبتبه عناصر معادل خود در M2.5 دارند.
درحالیکه برخیاز عناصر نیاز به ملاحظات ویژه دارند، نگاشتهای عملکرد زیر بهعنوان نقطه شروع توصیه میشوند:
در اینجا فهرستی از عناصر متداول «طراحی مواد ۳» و معادلهای «طراحی مواد ۲.۵» آنها ارائه شده است:
و در آخر، فهرستی از برخی عناصر مرتبط از کتابخانه Wear Compose Foundation:
| Wear Compose Foundation 1.7.0 | |
|---|---|
| androidx.wear.compose.foundation.hierarchicalFocusGroup | برای حاشیهنویسی عناصر ترکیبی در برنامه، برای پیگیری بخش فعال ترکیب، و هماهنگ کردن تمرکز استفاده میشود. |
| androidx.wear.compose.foundation.pager.HorizontalPager | صفحهگردی با پیمایش افقی که براساس مؤلفههای Compose Foundation با بهبودهای ویژه Wear ساخته شده است تا عملکرد و رعایت دستورالعملهای Wear OS را بهبود بخشد. |
| androidx.wear.compose.foundation.pager.VerticalPager | صفحهبندی با پیمایش عمودی که براساس مؤلفههای Compose Foundation با بهبودهای ویژه Wear ساخته شده است تا عملکرد و پایبندی به دستورالعملهای Wear OS را بهبود بخشد. |
| androidx.wear.compose.foundation.lazy.TransformingLazyColumn | میتواند بهجای ScalingLazyColumn برای افزودن جلوههای تبدیل پیمایش به هر مورد استفاده شود. |
دکمهها
دکمههای M3 با M2.5 متفاوت است. «تراشه M2.5» با
«دکمه» جایگزین شده است. پیادهسازی Button مقادیر پیشفرض را برای Text
maxLines و textAlign ارائه میدهد. این مقادیر پیشفرض را میتوان در عنصر Text
لغو کرد.
M2.5
import androidx.wear.compose.material.Chip
//M2.5 Buttons
Chip(...)
CompactChip(...)
Button(...)
M3
//M3 Buttons Button(onClick = { }){} CompactButton(onClick = { }){} IconButton(onClick = { }){} TextButton(onClick = { }){}
M3 همچنین شامل انواع جدید دکمه است. آنها را در نمای کلی مرجع میانای برنامهسازی کاربردی 3 Compose Material بررسی کنید.
M3 دکمه جدیدی معرفی میکند: EdgeButton. EdgeButton در ۴
اندازه مختلف دردسترس است: بسیار کوچک، کوچک، متوسط، و بزرگ. پیادهسازی EdgeButton
مقدار پیشفرضی برای maxLines براساس اندازه ارائه میدهد
که میتواند سفارشیسازی شود.
اگر از TransformingLazyColumn یا ScalingLazyColumn استفاده میکنید،
EdgeButton را به ScreenScaffold منتقل کنید تا تغییر شکل دهد و شکل آن با پیمایش تغییر کند،
بهجای اینکه EdgeButton بهعنوان آخرین مورد فهرست اضافه شود. برای بررسی نحوه استفاده از EdgeButton با ScreenScaffold و
TransformingLazyColumn، کد زیر را ببینید.
val state = rememberTransformingLazyColumnState() ScreenScaffold( scrollState = state, edgeButton = { EdgeButton( onClick = { }, modifier = Modifier.scrollable( state, orientation = Orientation.Vertical, reverseDirection = true, // Apply overscroll to the EdgeButton for proper scrolling behavior. overscrollEffect = rememberOverscrollEffect(), ), ) { Text(stringResource(R.string.show)) } }, ) { contentPadding -> TransformingLazyColumn(state = state, contentPadding = contentPadding) { // additional code here // ... } }
داربست
داربست در M3 با M2.5 متفاوت است. در M3، AppScaffold و
ScreenScaffold قابل ترکیب جدید جایگزین Scaffold شدهاند. AppScaffold و
ScreenScaffold ساختار صفحهنمایش را چیدمان میکنند و انتقالهای
عناصر ScrollIndicator و TimeText را هماهنگ میکنند.
AppScaffold به عناصر ثابت صفحهنمایش مانند TimeText اجازه میدهد درحین انتقالهای درونبرنامهای مانند کشیدن برای بستن، قابلمشاهده باقی بمانند. جایی برای
محتوای اصلی برنامه فراهم میکند که معمولاً توسط یک عنصر پیمایش مثل SwipeDismissableNavHost تأمین میشود
یک AppScaffold برای «فعالیت» تعریف میکنید و از یک ScreenScaffold برای هر
«صفحه» استفاده میکنید.
AppScaffold یک عنصر TimeText پیشفرض به صفحهها اضافه میکند. اگر میخواهید آن را بااستفاده از پارامتر timeText سفارشیسازی کنید، میتوانید آن را ملغی کنید.
M2.5
import androidx.wear.compose.material.Scaffold
Scaffold {...}
M3
AppScaffold { val navController = rememberSwipeDismissableNavController() SwipeDismissableNavHost( navController = navController, startDestination = "message_list" ) { composable("message_list") { MessageList(onMessageClick = { id -> navController.navigate("message_detail/$id") }) } composable("message_detail/{id}") { MessageDetail(id = it.arguments?.getString("id")!!) } } } } // Implementation of one of the screens in the navigation @Composable fun MessageDetail(id: String) { // .. Screen level content goes here val scrollState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = scrollState, ) { contentPadding -> // Screen content goes here // ...
اگر از HorizontalPager با HorizontalPageIndicator استفاده میکنید، میتوانید به HorizontalPagerScaffold
انتقال دهید. HorizontalPagerScaffold در AppScaffold قرار میگیرد. AppScaffold و HorizontalPagerScaffold ساختار «صفحهبندی» را
طراحی میکنند و انتقالهای
عناصر HorizontalPageIndicator و TimeText را هماهنگ میکنند.
HorizontalPagerScaffold بهطور پیشفرض HorizontalPageIndicator را در
مرکز انتهای صفحه نمایش میدهد و نمایش و پنهان کردن
TimeText و HorizontalPageIndicator را براساس اینکه Pager
صفحهبندی میشود یا نه هماهنگ میکند، این مورد توسط PagerState تعیین میشود.
همچنین عنصر جدید AnimatedPage وجود دارد که صفحهای را در
«صفحهگرد» با جلوه مقیاسبندی و سایه براساس موقعیتش پویانمایی میکند.
AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, flingBehavior = PagerScaffoldDefaults.snapWithSpringFlingBehavior( state = pagerState ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { val columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding, ) { item { ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding( ListHeaderDefaults.minimumTopListContentPadding ), transformation = SurfaceTransformation(transformationSpec), ) { Text(text = "Pager sample") } } item { Card( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding( CardDefaults.minimumVerticalListContentPadding ), transformation = SurfaceTransformation(transformationSpec), ) { if (page == 0) { Text(text = "Page #$page. Swipe right") } else { Text(text = "Page #$page. Swipe left and right") } } } } } } } } }
در نهایت، M3 یک VerticalPagerScaffold را معرفی میکند که از همان الگوی HorizontalPagerScaffold پیروی میکند:
@Composable fun VerticalPagerScaffoldSample() { AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPagerScaffold(pagerState = pagerState) { VerticalPager( state = pagerState, flingBehavior = PagerScaffoldDefaults.snapWithSpringFlingBehavior( state = pagerState ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { Text(text = "Page #$page") Spacer(modifier = Modifier.height(8.dp)) Text(text = "Swipe up and down") } } } } } } }
Placeholder
بین M2.5 و M3 تغییراتی در API وجود دارد. M3 دو اصلاحگر جایبان ارائه میدهد:
Modifier.placeholder، که بهجای محتوایی که هنوز بار نشده است کشیده میشود- جلوه درخشان جایبان
Modifier.placeholderShimmerکه جلوه درخشان جایبانی را ارائه میدهد که در حلقه پویانمایی اجرا میشود و منتظر میماند تا دادهها بار شود.
برای تغییرات بیشتر در عنصر Placeholder، جدول زیر را ببینید.
| M2.5 | M3 |
|---|---|
PlaceholderState.startPlaceholderAnimation |
برداشته شده است |
PlaceholderState.placeholderProgression |
برداشته شده است |
PlaceholderState.isShowContent |
جایگزینشده با PlaceholderState.isVisible (بولی معکوس) |
PlaceholderState.isWipeOff |
برداشته شده است |
PlaceholderDefaults.painterWithPlaceholderOverlayBackgroundBrush |
برداشته شده است |
PlaceholderDefaults.placeholderBackgroundBrush |
برداشته شده است |
PlaceholderDefaults.placeholderChipColors |
برداشته شده است |
SwipeDismissableNavHost
SwipeDismissableNavHost بخشی از wear.compose.navigation است. وقتی این
عنصر با M3 استفاده شود، M3 MaterialTheme
LocalSwipeToDismissBackgroundScrimColor و
LocalSwipeToDismissContentScrimColor را بهروز میکند.
TransformingLazyColumn
TransformingLazyColumn بخشی از androidx.wear.compose.foundation.lazy است و
از پویانماییهای تغییر شکل و مقیاسبندی در عناصر فهرست درحین پیمایش پشتیبانی میکند و
تجربه کاربری را بهبود میبخشد. بهشدت توصیه میشود که برنامهها از
ScalingLazyColumn به TransformingLazyColumn انتقال یابند.
مشابه ScalingLazyColumn، این ویژگی
rememberTransformingLazyColumnState() را برای ایجاد
TransformingLazyColumnState ارائه میدهد که در سراسر قطعات موسیقی بهیاد میماند.
برای افزودن پویانماییهای تغییر مقیاس و تغییر شکل، موارد زیر را به هر مورد فهرست اضافه کنید:
-
Modifier.transformedHeightکه به شما امکان میدهد ارتفاع تبدیلشده عناصر را بااستفاده ازTransformationSpecمحاسبه کنید، میتوانید ازrememberTransformationSpec()استفاده کنید، مگر اینکه به سفارشیسازی بیشتری نیاز داشته باشید. -
SurfaceTransformation
برای تأیید اینکه حاشیه در بالا و پایین فهرست درست است، از
minimumVerticalContentPadding اصلاحگر استفاده کنید.
val columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding ) { item { ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding), transformation = SurfaceTransformation(transformationSpec) ) { Text(text = "Header") } } // ... other items item { Button( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding), transformation = SurfaceTransformation(transformationSpec), onClick = { /* ... */ }, icon = { Icon( imageVector = Icons.Default.Build, contentDescription = "build", ) }, ) { Text( text = "Build", maxLines = 1, overflow = TextOverflow.Ellipsis, ) } } } }
پیوندهای مفید
برای کسب اطلاعات بیشتر درباره انتقال از M2.5 به M3 در Compose، به منابع تکمیلی زیر مراجعه کنید.