از Material 2 به Material 3 در Compose مهاجرت کنید

Material Design 3 تکامل بعدی متریال دیزاین است. این شامل تم به روز شده، اجزا و ویژگی های شخصی سازی Material You مانند رنگ پویا است. این به‌روزرسانی برای Material Design 2 است و با سبک بصری جدید و رابط کاربری سیستم در Android 12 و بالاتر هماهنگ است.

این راهنما بر مهاجرت از کتابخانه Compose Material (androidx.compose.material) Jetpack به Compose Material 3 (androidx.compose.material3) Jetpack تمرکز دارد.

رویکردها

به طور کلی ، نباید از M2 و M3 در یک برنامه به مدت طولانی استفاده کنید . این به دلیل این واقعیت است که دو سیستم طراحی و کتابخانه های مربوطه از نظر طراحی UX/UI و پیاده سازی Compose تفاوت قابل توجهی دارند.

برنامه شما ممکن است از یک سیستم طراحی استفاده کند، مانند سیستمی که با استفاده از Figma ایجاد شده است. در چنین مواردی، ما نیز به شدت توصیه می کنیم که شما یا تیم طراحی خود، قبل از شروع مهاجرت Compose، آن را از M2 به M3 منتقل کنید. اگر طراحی UX/UI آن مبتنی بر M2 باشد، انتقال یک برنامه به M3 منطقی نیست.

علاوه بر این، رویکرد شما برای مهاجرت باید بسته به اندازه، پیچیدگی و طراحی UX/UI برنامه شما متفاوت باشد. انجام این کار به شما کمک می کند تا تأثیر را بر پایگاه کد خود به حداقل برسانید. برای مهاجرت باید رویکردی مرحله‌ای داشته باشید.

چه زمانی مهاجرت کنیم

شما باید هر چه زودتر مهاجرت را شروع کنید. با این حال، مهم است که در نظر بگیرید که آیا برنامه شما در موقعیت واقعی برای انتقال کامل از M2 به M3 قرار دارد یا خیر. برخی از سناریوهای مسدودکننده وجود دارد که باید قبل از شروع بررسی کنید:

سناریو رویکرد توصیه شده
بدون مسدود کننده مهاجرت مرحله‌ای را آغاز کنید
جزء M2 هنوز در M3 موجود نیست. بخش اجزا و طرح‌بندی را در زیر ببینید. مهاجرت مرحله‌ای را آغاز کنید
شما یا تیم طراحی شما سیستم طراحی برنامه را از M2 به M3 منتقل نکرده اید سیستم طراحی را از M2 به M3 منتقل کنید، سپس مهاجرت مرحله‌ای را آغاز کنید

حتی اگر تحت تأثیر سناریوهای فوق قرار گرفته اید، باید قبل از انجام و انتشار به روز رسانی برنامه، یک رویکرد مرحله به مرحله برای مهاجرت داشته باشید. در این موارد، از M2 و M3 در کنار یکدیگر استفاده می‌کنید و در حین مهاجرت به M3، به تدریج M2 را حذف می‌کنید.

رویکرد مرحله‌ای

مراحل کلی برای مهاجرت مرحله ای به شرح زیر است:

  1. وابستگی M3 را در کنار وابستگی M2 اضافه کنید.
  2. نسخه(های) M3 طرح(های) برنامه خود را در کنار نسخه(های) M2 تم(های) برنامه خود اضافه کنید.
  3. بسته به اندازه و پیچیدگی برنامه خود، ماژول‌ها، صفحه‌ها یا اجزای سازنده را به M3 منتقل کنید (برای جزئیات به بخش‌های زیر مراجعه کنید).
  4. پس از انتقال کامل، نسخه(های) M2 تم(های) برنامه خود را حذف کنید.
  5. وابستگی M2 را حذف کنید.

وابستگی ها

M3 دارای یک بسته و نسخه جداگانه برای M2 است:

M2

implementation "androidx.compose.material:material:$m2-version"

M3

implementation "androidx.compose.material3:material3:$m3-version"

آخرین نسخه های M3 را در صفحه انتشارات Compose Material 3 ببینید.

سایر وابستگی های مواد خارج از کتابخانه های اصلی M2 و M3 تغییر نکرده اند. آنها از ترکیبی از بسته‌ها و نسخه‌های M2 و M3 استفاده می‌کنند، اما این تأثیری بر مهاجرت ندارد. آنها را می توان همانطور که با M3 استفاده کرد:

کتابخانه بسته و نسخه
نمادهای مواد را بنویسید androidx.compose.material:material-icons-*:$m2-version
ریپل مواد را بنویسید androidx.compose.material:material-ripple:$m2-version

APIهای آزمایشی

برخی از API های M3 آزمایشی در نظر گرفته می شوند. در چنین مواردی باید در سطح عملکرد یا فایل با استفاده از حاشیه نویسی ExperimentalMaterial3Api انتخاب کنید:

import androidx.compose.material3.ExperimentalMaterial3Api

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
    // M3 composables
}

موضوع بندی

هم در M2 و هم در M3، تم قابل ترکیب MaterialTheme نام دارد اما بسته‌ها و پارامترهای واردات متفاوت است:

M2

import androidx.compose.material.MaterialTheme

MaterialTheme(
    colors = AppColors,
    typography = AppTypography,
    shapes = AppShapes
) {
    // M2 content
}

M3

import androidx.compose.material3.MaterialTheme

MaterialTheme(
    colorScheme = AppColorScheme,
    typography = AppTypography,
    shapes = AppShapes
) {
    // M3 content
}

رنگ

مقایسه سیستم های رنگی M2 به M3
شکل 1 . سیستم رنگی M2 (چپ) در مقابل سیستم رنگی M3 (راست).

سیستم رنگ در M3 تفاوت قابل توجهی با M2 دارد. تعداد پارامترهای رنگ افزایش یافته است، نام‌های متفاوتی دارند و به‌طور متفاوتی به اجزای M3 نگاشت می‌شوند. در Compose، این برای کلاس M2 Colors ، کلاس M3 ColorScheme و توابع مرتبط اعمال می شود:

M2

import androidx.compose.material.lightColors
import androidx.compose.material.darkColors

val AppLightColors = lightColors(
    // M2 light Color parameters
)
val AppDarkColors = darkColors(
    // M2 dark Color parameters
)
val AppColors = if (darkTheme) {
    AppDarkColors
} else {
    AppLightColors
}

M3

import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme

val AppLightColorScheme = lightColorScheme(
    // M3 light Color parameters
)
val AppDarkColorScheme = darkColorScheme(
    // M3 dark Color parameters
)
val AppColorScheme = if (darkTheme) {
    AppDarkColorScheme
} else {
    AppLightColorScheme
}

با توجه به تفاوت های قابل توجه بین سیستم های رنگی M2 و M3، هیچ نقشه منطقی برای پارامترهای Color وجود ندارد. در عوض، از ابزار Material Theme Builder برای ایجاد یک طرح رنگی M3 استفاده کنید. از رنگ‌های M2 به‌عنوان رنگ‌های منبع اصلی در ابزار استفاده کنید، که ابزار به پالت‌های رنگی مورد استفاده در طرح رنگ M3 گسترش می‌دهد. نگاشت های زیر به عنوان نقطه شروع توصیه می شود:

M2 سازنده تم مواد
primary اولیه
primaryVariant ثانویه
secondary دوره سوم
surface یا background خنثی
رنگ‌های M2 در Material Theme Builder برای ایجاد یک طرح رنگی M3 استفاده می‌شوند
شکل 2 . رنگ‌های M2 Jetchat در Material Theme Builder برای ایجاد یک طرح رنگی M3 استفاده می‌شوند.

می توانید مقادیر کد هگز رنگی برای تم های روشن و تاریک را از ابزار کپی کنید و از آنها برای پیاده سازی یک نمونه M3 ColorScheme استفاده کنید. متناوبا، Material Theme Builder می‌تواند کد Compose را صادر کند.

isLight

برخلاف کلاس M2 Colors ، کلاس M3 ColorScheme شامل پارامتر isLight نمی شود. به طور کلی باید سعی کنید و هر آنچه که به این اطلاعات نیاز دارد را در سطح موضوع مدل کنید. به عنوان مثال:

M2

import androidx.compose.material.lightColors
import androidx.compose.material.darkColors
import androidx.compose.material.MaterialTheme

@Composable
private fun AppTheme(
  darkTheme: Boolean = isSystemInDarkTheme(),
  content: @Composable () -> Unit
) {
  val colors = if (darkTheme) darkColors(…) else lightColors(…)
  MaterialTheme(
      colors = colors,
      content = content
  )
}

@Composable
fun AppComposable() {
    AppTheme {
        val cardElevation = if (MaterialTheme.colors.isLight) 0.dp else 4.dp
        …
    }
}

M3

import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.MaterialTheme

val LocalCardElevation = staticCompositionLocalOf { Dp.Unspecified }
@Composable
private fun AppTheme(
   darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
   val cardElevation = if (darkTheme) 4.dp else 0.dp
    CompositionLocalProvider(LocalCardElevation provides cardElevation) {
        val colorScheme = if (darkTheme) darkColorScheme(…) else lightColorScheme(…)
        MaterialTheme(
            colorScheme = colorScheme,
            content = content
        )
    }
}

@Composable
fun AppComposable() {
    AppTheme {
        val cardElevation = LocalCardElevation.current
        …
    }
}

برای اطلاعات بیشتر به سیستم‌های طراحی سفارشی در راهنمای Compose مراجعه کنید.

رنگ پویا

یک ویژگی جدید در M3 رنگ پویا است. به جای استفاده از رنگ‌های سفارشی، یک M3 ColorScheme می‌تواند از رنگ‌های کاغذدیواری دستگاه در Android 12 و بالاتر با استفاده از عملکردهای زیر استفاده کند:

تایپوگرافی

مقایسه سیستم های تایپوگرافی M2 و M3
شکل 3 . سیستم تایپوگرافی M3 (چپ) در مقابل سیستم تایپوگرافی M2 (راست)

سیستم تایپوگرافی در M3 با M2 متفاوت است. تعداد پارامترهای تایپوگرافی تقریباً یکسان است، اما نام‌های متفاوتی دارند و به مولفه‌های M3 نگاشت متفاوتی دارند. در Compose، این برای کلاس Typography M2 و کلاس Typography M3 اعمال می شود:

M2

import androidx.compose.material.Typography

val AppTypography = Typography(
    // M2 TextStyle parameters
)

M3

import androidx.compose.material3.Typography

val AppTypography = Typography(
    // M3 TextStyle parameters
)

نگاشت پارامترهای TextStyle زیر به عنوان نقطه شروع توصیه می شود:

M2 M3
h1 displayLarge
h2 displayMedium
h3 displaySmall
N/A headlineLarge
h4 headlineMedium
h5 headlineSmall
h6 titleLarge
subtitle1 titleMedium
subtitle2 titleSmall
body1 bodyLarge
body2 bodyMedium
caption bodySmall
button labelLarge
N/A labelMedium
overline labelSmall

شکل

مقایسه سیستم های شکل M2 و M3
شکل 4 . سیستم شکل M2 (چپ) در مقابل سیستم شکل M3 (راست)

سیستم شکل در M3 با M2 متفاوت است. تعداد پارامترهای شکل افزایش یافته است، نام‌گذاری‌های متفاوتی دارند و به‌طور متفاوتی به اجزای M3 نگاشت می‌شوند. در Compose، این برای کلاس M2 Shapes و کلاس M3 Shapes اعمال می شود:

M2

import androidx.compose.material.Shapes

val AppShapes = Shapes(
    // M2 Shape parameters
)

M3

import androidx.compose.material3.Shapes

val AppShapes = Shapes(
    // M3 Shape parameters
)

نگاشت پارامتر Shape زیر به عنوان نقطه شروع توصیه می شود:

M2 M3
N/A extraSmall
small small
medium medium
large large
N/A extraLarge

اجزا و چیدمان ها

اکثر اجزا و طرح‌بندی‌های M2 در M3 موجود هستند. با این حال، برخی از مفقودان و همچنین موارد جدیدی وجود دارند که در M2 وجود نداشتند. علاوه بر این، برخی از اجزای M3 تغییرات بیشتری نسبت به معادل های خود در M2 دارند. به طور کلی سطوح M3 API سعی می کنند تا حد امکان شبیه نزدیک ترین معادل های خود در M2 باشند.

با توجه به سیستم های رنگ، تایپوگرافی و شکل به روز شده، اجزای M3 تمایل دارند به طور متفاوتی با مقادیر موضوعی جدید نگاشت شوند. ایده خوبی است که دایرکتوری توکن ها را در کد منبع Compose Material 3 به عنوان منبع حقیقت برای این نگاشت ها بررسی کنید.

در حالی که برخی از مؤلفه ها نیاز به ملاحظات خاصی دارند، نگاشت تابع زیر به عنوان نقطه شروع توصیه می شود:

API های از دست رفته :

M2 M3
androidx.compose.material.swipeable هنوز در دسترس نیست

APIهای جایگزین شده :

M2 M3
androidx.compose.material.BackdropScaffold معادل M3 وجود ندارد، به جای آن به Scaffold یا BottomSheetScaffold مهاجرت کنید
androidx.compose.material.BottomDrawer معادل M3 وجود ندارد، به جای آن به ModalBottomSheet مهاجرت کنید

API های تغییر نام یافته :

M2 M3
androidx.compose.material.BottomNavigation androidx.compose.material3.NavigationBar
androidx.compose.material.BottomNavigationItem androidx.compose.material3.NavigationBarItem
androidx.compose.material.Chip androidx.compose.material3.AssistChip یا androidx.compose.material3.SuggestionChip
androidx.compose.material.ModalBottomSheetLayout androidx.compose.material3.ModalBottomSheet
androidx.compose.material.ModalDrawer androidx.compose.material3.ModalNavigationDrawer

همه API های دیگر :

M2 M3
androidx.compose.material.AlertDialog androidx.compose.material3.AlertDialog
androidx.compose.material.Badge androidx.compose.material3.Badge
androidx.compose.material.BadgedBox androidx.compose.material3.BadgedBox
androidx.compose.material.BottomAppBar androidx.compose.material3.BottomAppBar
androidx.compose.material.BottomSheetScaffold androidx.compose.material3.BottomSheetScaffold
androidx.compose.material.Button androidx.compose.material3.Button
androidx.compose.material.Card androidx.compose.material3.Card
androidx.compose.material.Checkbox androidx.compose.material3.Checkbox
androidx.compose.material.CircularProgressIndicator androidx.compose.material3.CircularProgressIndicator
androidx.compose.material.Divider androidx.compose.material3.Divider
androidx.compose.material.DropdownMenu androidx.compose.material3.DropdownMenu
androidx.compose.material.DropdownMenuItem androidx.compose.material3.DropdownMenuItem
androidx.compose.material.ExposedDropdownMenuBox androidx.compose.material3.ExposedDropdownMenuBox
androidx.compose.material.ExtendedFloatingActionButton androidx.compose.material3.ExtendedFloatingActionButton
androidx.compose.material.FilterChip androidx.compose.material3.FilterChip
androidx.compose.material.FloatingActionButton androidx.compose.material3.FloatingActionButton
androidx.compose.material.Icon androidx.compose.material3.Icon
androidx.compose.material.IconButton androidx.compose.material3.IconButton
androidx.compose.material.IconToggleButton androidx.compose.material3.IconToggleButton
androidx.compose.material.LeadingIconTab androidx.compose.material3.LeadingIconTab
androidx.compose.material.LinearProgressIndicator androidx.compose.material3.LinearProgressIndicator
androidx.compose.material.ListItem androidx.compose.material3.ListItem
androidx.compose.material.NavigationRail androidx.compose.material3.NavigationRail
androidx.compose.material.NavigationRailItem androidx.compose.material3.NavigationRailItem
androidx.compose.material.OutlinedButton androidx.compose.material3.OutlinedButton
androidx.compose.material.OutlinedTextField androidx.compose.material3.OutlinedTextField
androidx.compose.material.RadioButton androidx.compose.material3.RadioButton
androidx.compose.material.RangeSlider androidx.compose.material3.RangeSlider
androidx.compose.material.Scaffold androidx.compose.material3.Scaffold
androidx.compose.material.ScrollableTabRow androidx.compose.material3.ScrollableTabRow
androidx.compose.material.Slider androidx.compose.material3.Slider
androidx.compose.material.Snackbar androidx.compose.material3.Snackbar
androidx.compose.material.Switch androidx.compose.material3.Switch
androidx.compose.material.Tab androidx.compose.material3.Tab
androidx.compose.material.TabRow androidx.compose.material3.TabRow
androidx.compose.material.Text androidx.compose.material3.Text
androidx.compose.material.TextButton androidx.compose.material3.TextButton
androidx.compose.material.TextField androidx.compose.material3.TextField
androidx.compose.material.TopAppBar androidx.compose.material3.TopAppBar
androidx.compose.material.TriStateCheckbox androidx.compose.material3.TriStateCheckbox

آخرین مؤلفه‌ها و طرح‌بندی‌های M3 را در نمای کلی مرجع Compose Material 3 API مشاهده کنید و به صفحه انتشارات برای APIهای جدید و به‌روز نگاه کنید.

داربست، اسنک بار و کشوی ناوبری

مقایسه داربست M2 و M3 با اسنک بار و کشو ناوبری
شکل 5 . داربست M2 با اسنک بار و کشوی ناوبری (سمت چپ) در مقابل داربست M3 با اسنک بار و کشوی ناوبری (راست).

داربست در M3 با M2 متفاوت است. در هر دو M2 و M3، چیدمان اصلی قابل ترکیب Scaffold نام دارد اما بسته‌ها و پارامترهای واردات متفاوت هستند:

M2

import androidx.compose.material.Scaffold

Scaffold(
    // M2 scaffold parameters
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    // M3 scaffold parameters
)

Scaffold M2 حاوی یک پارامتر backgroundColor است که اکنون در Scaffold M3 به containerColor نامگذاری شده است:

M2

import androidx.compose.material.Scaffold

Scaffold(
    backgroundColor = …,
    content = { … }
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    containerColor = …,
    content = { … }
)

کلاس M2 ScaffoldState دیگر در M3 وجود ندارد زیرا حاوی پارامتر drawerState است که دیگر مورد نیاز نیست. برای نمایش نوارهای اسنک با Scaffold M3، به جای آن از SnackbarHostState استفاده کنید:

M2

import androidx.compose.material.Scaffold
import androidx.compose.material.rememberScaffoldState

val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()

Scaffold(
    scaffoldState = scaffoldState,
    content = {
        …
        scope.launch {
            scaffoldState.snackbarHostState.showSnackbar(…)
        }
    }
)

M3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()

Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    content = {
        …
        scope.launch {
            snackbarHostState.showSnackbar(…)
        }
    }
)

تمام پارامترهای drawer* از Scaffold M2 از Scaffold M3 حذف شده است. اینها شامل پارامترهایی مانند drawerShape و drawerContent هستند. برای نشان دادن یک کشو با Scaffold M3، به جای آن از یک کشوی ناوبری قابل ترکیب، مانند ModalNavigationDrawer استفاده کنید:

M2

import androidx.compose.material.DrawerValue
import
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberDrawerState
import androidx.compose.material.rememberScaffoldState

val scaffoldState = rememberScaffoldState(
    drawerState = rememberDrawerState(DrawerValue.Closed)
)
val scope = rememberCoroutineScope()

Scaffold(
    scaffoldState = scaffoldState,
    drawerContent = { … },
    drawerGesturesEnabled = …,
    drawerShape = …,
    drawerElevation = …,
    drawerBackgroundColor = …,
    drawerContentColor = …,
    drawerScrimColor = …,
    content = {
        …
        scope.launch {
            scaffoldState.drawerState.open()
        }
    }
)

M3

import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.rememberDrawerState

val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()

ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet(
            drawerShape = …,
            drawerTonalElevation = …,
            drawerContainerColor = …,
            drawerContentColor = …,
            content = { … }
        )
    },
    gesturesEnabled = …,
    scrimColor = …,
    content = {
        Scaffold(
            content = {
                …
                scope.launch {
                    drawerState.open()
                }
            }
        )
    }
)

نوار برنامه بالا

مقایسه داربست M2 و M3 با نوار برنامه بالا و لیست پیمایش شده
شکل 6 . داربست M2 با نوار برنامه بالا و لیست پیمایش شده (چپ) در مقابل داربست M3 با نوار برنامه بالا و لیست پیمایش شده (راست)

نوارهای برنامه برتر در M3 با نوارهای M2 متفاوت است. در هر دو M2 و M3، نوار اصلی برنامه بالا که می‌توان آن را ترکیب کرد TopAppBar نام دارد، اما بسته‌ها و پارامترهای واردات متفاوت هستند:

M2

import androidx.compose.material.TopAppBar

TopAppBar(…)

M3

import androidx.compose.material3.TopAppBar

TopAppBar(…)

اگر قبلاً محتوا را در M2 TopAppBar متمرکز می‌کردید، از M3 CenterAlignedTopAppBar استفاده کنید. خوب است که از MediumTopAppBar و LargeTopAppBar نیز آگاه باشید.

نوارهای بالای برنامه M3 حاوی یک پارامتر scrollBehavior جدید برای ارائه عملکردهای مختلف در اسکرول در کلاس TopAppBarScrollBehavior ، مانند تغییر ارتفاع است. این در ارتباط با پیمایش محتوا از طریق Modifer.nestedScroll کار می کند. این در M2 TopAppBar با تغییر دستی پارامتر elevation امکان پذیر شد:

M2

import androidx.compose.material.AppBarDefaults
import androidx.compose.material.Scaffold
import androidx.compose.material.TopAppBar

val state = rememberLazyListState()
val isAtTop by remember {
    derivedStateOf {
        state.firstVisibleItemIndex == 0 && state.firstVisibleItemScrollOffset == 0
    }
}

Scaffold(
    topBar = {
        TopAppBar(
            elevation = if (isAtTop) {
                0.dp
            } else {
                AppBarDefaults.TopAppBarElevation
            },
            …
        )
    },
    content = {
        LazyColumn(state = state) { … }
    }
)

M3

import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults

val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()

Scaffold(
    modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
    topBar = {
        TopAppBar(
            scrollBehavior = scrollBehavior,
            …
        )
    },
    content = {
        LazyColumn { … }
    }
)

ناوبری پایین / نوار ناوبری

مقایسه ناوبری پایین M2 و نوار ناوبری M3
شکل 7 . ناوبری پایین M2 (چپ) در مقابل نوار ناوبری M3 (راست).

ناوبری پایین در M2 به نوار ناوبری در M3 تغییر نام داده است. در M2 قابل ترکیب BottomNavigation و BottomNavigationItem هستند، در حالی که در M3 NavigationBar و NavigationBarItem composable وجود دارند:

M2

import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem

BottomNavigation {
    BottomNavigationItem(…)
    BottomNavigationItem(…)
    BottomNavigationItem(…)
}

M3

import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem

NavigationBar {
    NavigationBarItem(…)
    NavigationBarItem(…)
    NavigationBarItem(…)
}

دکمه ها، دکمه های نماد و FAB ها

مقایسه دکمه های M2 و M3
شکل 8 . دکمه های M2 (چپ) در مقابل دکمه های M3 (راست)

دکمه‌ها، دکمه‌های نماد و دکمه‌های عمل شناور (FAB) در M3 با دکمه‌های M2 متفاوت هستند. M3 شامل همه دکمه‌های M2 می‌شود:

M2

import androidx.compose.material.Button
import androidx.compose.material.ExtendedFloatingActionButton
import androidx.compose.material.FloatingActionButton
import androidx.compose.material.IconButton
import androidx.compose.material.IconToggleButton
import androidx.compose.material.OutlinedButton
import androidx.compose.material.TextButton

// M2 buttons
Button(…)
OutlinedButton(…)
TextButton(…)
// M2 icon buttons
IconButton(…)
IconToggleButton(…)
// M2 FABs
FloatingActionButton(…)
ExtendedFloatingActionButton(…)

M3

import androidx.compose.material3.Button
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.TextButton

// M3 buttons
Button(…)
OutlinedButton(…)
TextButton(…)
// M3 icon buttons
IconButton(…)
IconToggleButton(…)
// M3 FABs
FloatingActionButton(…)
ExtendedFloatingActionButton(…)

M3 همچنین شامل تغییرات دکمه های جدید است. آنها را در نمای کلی مرجع Compose Material 3 API بررسی کنید.

سوئیچ

مقایسه سوئیچ های M2 و M3
شکل 9 . سوئیچ M2 (چپ) در مقابل سوئیچ M3 (راست).

سوئیچ در M3 با M2 متفاوت است. در هر دو M2 و M3، سوئیچ composable Switch نامیده می شود اما بسته های واردات متفاوت است:

M2

import androidx.compose.material.Switch

Switch(…)

M3

import androidx.compose.material3.Switch

Switch(…)

سطوح و ارتفاع

مقایسه ارتفاع سطح M2 و ارتفاع سطح M3 در تم های روشن و تاریک
شکل 10 . ارتفاع سطح M2 در مقابل ارتفاع سطح M3 در طرح زمینه روشن (چپ) و تم تیره (راست).

سیستم های سطح و ارتفاع در M3 با M2 متفاوت است. دو نوع ارتفاع در M3 وجود دارد:

  • ارتفاع سایه (مانند M2 سایه می اندازد)
  • ارتفاع تونال (روی یک رنگ، جدید به M3)

در Compose این برای عملکرد M2 Surface و M3 Surface اعمال می شود:

M2

import androidx.compose.material.Surface

Surface(
    elevation = …
) { … }

M3

import androidx.compose.material3.Surface

Surface(
    shadowElevation = …,
    tonalElevation = …
) { … }

بسته به ترجیح طراحی UX/UI، می‌توانید از مقادیر elevation Dp در M2 برای shadowElevation و/یا tonalElevation در M3 استفاده کنید. Surface پشتیانی است که در پشت اکثر کامپوننت‌ها قابل ترکیب است، بنابراین کامپوننت‌های composable نیز ممکن است پارامترهای ارتفاعی را که باید به همان روش مهاجرت کنید، نشان دهند.

ارتفاع تونال در M3 جایگزین مفهوم همپوشانی ارتفاع در تم های تاریک M2 می شود. در نتیجه ElevationOverlay و LocalElevationOverlay در M3 وجود ندارند و LocalAbsoluteElevation در M2 به LocalAbsoluteTonalElevation در M3 تغییر کرده است.

آلفای تاکید و محتوا

مقایسه آیکون M2 و M3 و تاکید متن
شکل 11 . تأکید بر روی نماد و متن M2 (چپ) در مقابل تأکید بر روی نماد و متن M3 (راست)

تاکید در M3 به طور قابل توجهی با M2 متفاوت است. در M2، تأکید بر استفاده از رنگ‌هایی با مقادیر آلفای خاص برای متمایز کردن محتوا مانند متن و نمادها است. در M3، اکنون چند رویکرد متفاوت وجود دارد:

  • استفاده از رنگ‌ها در کنار انواع آن‌ها روی رنگ‌های سیستم رنگی توسعه‌یافته M3.
  • استفاده از وزن فونت های مختلف برای متن

در نتیجه ContentAlpha و LocalContentAlpha در M3 وجود ندارند و باید جایگزین شوند.

نگاشت های زیر به عنوان نقطه شروع توصیه می شود:

M2 M3
onSurface با ContentAlpha.high onSurface به طور کلی، FontWeight.Medium - FontWeight.Black برای متن
onSurface با ContentAlpha.medium onSurfaceVariant به طور کلی، FontWeight.Thin - FontWeight.Normal برای متن
onSurface با ContentAlpha.disabled onSurface.copy(alpha = 0.38f)

در اینجا نمونه ای از تأکید بر نماد در M2 در مقابل M3 آمده است:

M2

import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
    Icon(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Icon(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Icon(…)
}

M3

import androidx.compose.material3.LocalContentColor

// High emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
    Icon(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant) {
    Icon(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
    Icon(…)
}

در اینجا نمونه هایی از تاکید متن در M2 و M3 آمده است:

M2

import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
    Text(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Text(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Text(…)
}

M3

import androidx.compose.material3.LocalContentColor

// High emphasis
Text(
    …,
    fontWeight = FontWeight.Bold
)
// Medium emphasis
Text(
    …,
    fontWeight = FontWeight.Normal
)
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
    Text(
        …,
        fontWeight = FontWeight.Normal
    )
}

پس زمینه و ظروف

پس زمینه ها در M2 کانتینرها در M3 نامیده می شوند. به طور کلی، می توانید با استفاده از همان مقادیر، پارامترهای background* را در M2 با container* در M3 جایگزین کنید. به عنوان مثال:

M2

Badge(
    backgroundColor = MaterialTheme.colors.primary
) { … }

M3

Badge(
    containerColor = MaterialTheme.colorScheme.primary
) { … }

برای کسب اطلاعات بیشتر در مورد مهاجرت از M2 به M3 در Compose، به منابع اضافی زیر مراجعه کنید.

اسناد

نمونه برنامه ها

ویدیوها

مرجع API و کد منبع

{% کلمه به کلمه %} {% آخر کلمه %} {% کلمه به کلمه %} {% آخر کلمه %}