از 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 و کد منبع

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

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 و کد منبع

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

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 را در صفحه نسخه 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 متفاوت هستند. در آهنگسازی ، این مربوط به کلاس 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 مورد استفاده در سازنده موضوع برای تولید یک طرح رنگی M3
شکل 2 . رنگهای M2 Jetchat که در سازنده موضوع مواد برای تولید یک طرح رنگ M3 استفاده می شود.

می توانید مقادیر کد Hex Color را برای تم های سبک و تاریک از ابزار کپی کرده و از آنها برای اجرای یک نمونه M3 ColorScheme استفاده کنید. از طرف دیگر ، سازنده موضوع مواد می تواند کد را صادر کند.

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
        
    }
}

برای اطلاعات بیشتر به سیستم های طراحی سفارشی در راهنمای آهنگسازی مراجعه کنید.

رنگ پویا

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

تایپوگرافی

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

سیستم تایپوگرافی در M3 با M2 متفاوت است. تعداد پارامترهای تایپوگرافی تقریباً یکسان است ، اما نامهای مختلفی دارند و با اجزای M3 متفاوت هستند. در آهنگسازی ، این مربوط به کلاس 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 نقشه می گیرند. در آهنگسازی ، این در مورد کلاس 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 هستند. به طور کلی سطوح API M3 سعی می کنند تا حد ممکن با نزدیکترین معادل آنها در M2 مشابه باشند.

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

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

API های گمشده :

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

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

M2 M3
androidx.compose.material.BackdropScaffold بدون معادل M3 BottomSheetScaffold به Scaffold
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 با Snackbar و کشو ناوبری
شکل 5 . داربست M2 با Snackbar و کشو ناوبری (سمت چپ) در مقابل داربست M3 با Snackbar و کشو ناوبری (سمت راست).

داربست در 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 اکنون به containerColor در Scaffold M3 نامگذاری شده است:

M2

import androidx.compose.material.Scaffold

Scaffold(
    backgroundColor = ,
    content = {  }
)

M3

import androidx.compose.material3.Scaffold

Scaffold(
    containerColor = ,
    content = {  }
)

کلاس ScaffoldState M2 دیگر در 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 ، مجموعه اصلی نوار برنامه Top Top TopAppBar نامگذاری شده است اما بسته ها و پارامترهای واردات متفاوت هستند:

M2

import androidx.compose.material.TopAppBar

TopAppBar()

M3

import androidx.compose.material3.TopAppBar

TopAppBar()

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

میله های برنامه Top 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 Composables NavigationBar و NavigationBarItem وجود دارد:

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()
}

دکمه ها ، دکمه های نماد و فاب

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

دکمه ها ، دکمه های نماد و دکمه های اکشن شناور (FABS) در 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 3 API بررسی کنید.

سوئیچ

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

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

M2

import androidx.compose.material.Switch

Switch()

M3

import androidx.compose.material3.Switch

Switch()

سطوح و ارتفاع

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

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

  • Elevation Shadow (سایه ای می گذارد ، همان M2)
  • ارتفاع تونال (پوشش رنگی ، جدید برای M3)

در آهنگسازی این مربوط به عملکرد Surface M2 و عملکرد Surface M3 است:

M2

import androidx.compose.material.Surface

Surface(
    elevation = 
) {  }

M3

import androidx.compose.material3.Surface

Surface(
    shadowElevation = ,
    tonalElevation = 
) {  }

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

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

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

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

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

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

در نتیجه ، ContentAlpha و LocalContentAlpha در M3 وجود ندارند و نیاز به تعویض دارند.

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

M2 M3
از ContentAlpha.high onSurface onSurface به طور کلی ، FontWeight.Medium - FontWeight.Black for text
onSurface ContentAlpha.medium وجود دارد onSurfaceVariant به طور کلی ، FontWeight.Thin - FontWeight.Normal for text
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 در آهنگسازی ، با منابع اضافی زیر مشورت کنید.

اسناد

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

ویدیوها

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

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