نقل البيانات من المادة 2 إلى المادة 3 في Compose

Material Design 3 هو الإصدار التالي من Material Design. ويشمل ذلك التصميم المتعدّد الأبعاد المُعدَّل والمكوّنات وميزات تخصيص Material You، مثل الألوان الديناميكية. وهو تحديث لـ Material Design 2 ومتوافق مع الأسلوب المرئي الجديد وواجهة مستخدم النظام على Android 12 والإصدارات الأحدث.

يركز هذا الدليل على نقل البيانات من مكتبة Compose Material (androidx.compose.material) في Jetpack إلى مكتبة Compose Material 3 (androidx.compose.material3) في Jetpack.

الاقتراحات

بشكل عام، يجب عدم استخدام كل من M2 وM3 في تطبيق واحد على المدى الطويل. ويعود سبب ذلك إلى أنّ نظامَي التصميم والمكتبتَين المعنيتَين يختلفان بشكل كبير من حيث تصميمات تجربة المستخدم/واجهة المستخدم وعمليات التنفيذ في Compose.

قد يستخدم تطبيقك نظام تصميم، مثل نظام تم إنشاؤه باستخدام Figma. في مثل هذه الحالات، ننصحك أيضًا بشدة بأن تنقل أنت أو فريق التصميم النموذج من M2 إلى M3 قبل بدء نقل المحتوى في Compose. لا يُجدي نفعًا نقل تطبيق إلى M3 إذا كان تصميم تجربة المستخدم أو واجهة المستخدم يستند إلى M2.

بالإضافة إلى ذلك، يجب أن يختلف نهج نقل البيانات حسب حجم تطبيقك وتعقيده وتصميم تجربة المستخدم/واجهة المستخدم. يساعدك ذلك في الحدّ من التأثير على قاعدة الرموز البرمجية. يجب اتّباع نهج تدريجي لعملية نقل البيانات.

حالات نقل البيانات

يجب بدء عملية نقل البيانات في أقرب وقت ممكن. ومع ذلك، من المهم مراعاة ما إذا كان تطبيقك في وضع واقعي لنقله بالكامل من الإصدار M2 إلى الإصدار M3. هناك بعض سيناريوهات الحظر التي يجب التحقيق فيها قبل البدء:

السيناريو الطريقة المُقترحة
عدم استخدام حظر بدء نقل البيانات على مراحل
لا يتوفّر مكوّن من M2 في M3 بعد. اطّلِع على قسم العناصر والتنسيقات أدناه. بدء نقل البيانات على مراحل
لم تنقل أنت أو فريق التصميم نظام تصميم التطبيق من الإصدار M2 إلى الإصدار M3. نقل نظام التصميم من M2 إلى M3، ثم بدء عملية نقل البيانات على مراحل

حتى إذا كنت متأثرًا بالسيناريوهات أعلاه، عليك اتّباع نهج تدريجي لنقل البيانات قبل إرسال تحديث التطبيق وإصداره. في هذه الحالات، ستستخدم M2 وM3 جنبًا إلى جنب، وستتوقف تدريجيًا عن استخدام M2 أثناء نقل البيانات إلى M3.

النهج المرحلي

في ما يلي الخطوات العامة لنقل البيانات على مراحل:

  1. أضِف تبعية M3 إلى جانب تبعية M2.
  2. أضِف إصدارات M3 لمظاهر تطبيقك إلى جانب إصدارات M2 لموضوعات تطبيقك.
  3. نقل الوحدات أو الشاشات أو العناصر القابلة للتجميع الفردية إلى M3، استنادًا إلى حجم تطبيقك وتعقيده (اطّلِع على الأقسام أدناه للاطّلاع على التفاصيل)
  4. بعد نقل البيانات بالكامل، أزِل إصدارات M2 من مظاهر تطبيقك.
  5. أزِل التبعية لـ M2.

التبعيات

تتوفّر حزمة وإصدار منفصلان لتطبيق M3 مقارنةً بتطبيق M2:

التصميم 2

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

التصميم 3

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

يمكنك الاطّلاع على أحدث إصدارات M3 في صفحة إصدارات Compose Material 3.

لم يتم تغيير التبعيات الأخرى لمواد العرض خارج مكتبتَي M2 وM3 الرئيسيتَين. يستخدمون مزيجًا من حِزم الإصدارَين M2 وM3، ولكنّ ذلك ليس له أثر في عملية نقل البيانات. ويمكن استخدامها كما هي مع M3:

المكتبة الحزمة والإصدار
إنشاء رموز Material Icons androidx.compose.material:material-icons-*:$m2-version
إنشاء تأثير تموج في التصميم androidx.compose.material:material-ripple:$m2-version

واجهات برمجة التطبيقات التجريبية

تُعتبر بعض واجهات برمجة تطبيقات M3 تجريبية. في هذه الحالات، عليك تفعيل الميزة على مستوى الدالة أو الملف باستخدام التعليق التوضيحي ExperimentalMaterial3Api:

import androidx.compose.material3.ExperimentalMaterial3Api

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

التصميم

في كلّ من M2 وM3، يتمّ تسمية عنصر تركيب المظهر MaterialTheme، ولكن تختلف حزم الاستيراد والمَعلمات:

التصميم 2

import androidx.compose.material.MaterialTheme

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

التصميم 3

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 والدوالّ ذات الصلة:

التصميم 2

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
}

التصميم 3

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 Design لإنشاء نظام ألوان M3. استخدِم ألوان M2 كألوان مصدر أساسية في الأداة، والتي توسّعها الأداة إلى لوحات ألوان متدرجة تستخدمها مجموعة ألوان M3. ننصحك باستخدام عمليات الربط التالية كأحد النقاط الأساسية:

التصميم 2 أداة إنشاء المظاهر المتوافقة مع لغة تصميم المواد
primary Primary
primaryVariant Secondary
secondary Tertiary
surface أو background لا إيجابية ولا سلبية
ألوان M2 المستخدَمة في أداة Material Theme Builder لإنشاء نظام ألوان M3
الشكل 2: ألوان M2 الخاصة بتطبيق Jetchat المستخدَمة في "أداة إنشاء المظاهر" من Material Design لإنشاء نظام ألوان M3

يمكنك نسخ قيم الرموز الست عشرية للألوان للمظهرين الفاتح والداكن من الأداة واستخدامها لتنفيذ مثيل ColorScheme في M3. بدلاً من ذلك، يمكن لأداة Material Theme Builder تصدير رمز Compose.

isLight

على عكس فئة M2 Colors، لا تتضمّن فئة M3 ColorScheme مَعلمة isLight. بشكل عام، عليك محاولة وضع نماذج لما يحتاج إلى هذه المعلومات على مستوى المظهر. مثلاً:

التصميم 2

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

التصميم 3

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، ينطبق ذلك على فئة M2 Typography وفئة M3 Typography:

التصميم 2

import androidx.compose.material.Typography

val AppTypography = Typography(
    // M2 TextStyle parameters
)

التصميم 3

import androidx.compose.material3.Typography

val AppTypography = Typography(
    // M3 TextStyle parameters
)

ننصحك باستخدام عمليات ربط المَعلمات TextStyle التالية كنقطة بدء:

التصميم 2 التصميم 3
h1 displayLarge
h2 displayMedium
h3 displaySmall
لا ينطبق headlineLarge
h4 headlineMedium
h5 headlineSmall
h6 titleLarge
subtitle1 titleMedium
subtitle2 titleSmall
body1 bodyLarge
body2 bodyMedium
caption bodySmall
button labelLarge
لا ينطبق labelMedium
overline labelSmall

شكل

مقارنة بين نظامَي الأشكال M2 وM3
الشكل 4. نظام أشكال M2 (على يمين الصفحة) في مقابل نظام أشكال M3 (على يمين الصفحة)

يختلف نظام الأشكال في M3 عن M2. لقد زاد عدد مَعلمات شكل ، وتم تسميتها بشكلٍ مختلف وتتطابق بشكلٍ مختلف مع مكونات M3. في Compose، ينطبق ذلك على فئة M2 Shapes وفئة M3 Shapes:

التصميم 2

import androidx.compose.material.Shapes

val AppShapes = Shapes(
    // M2 Shape parameters
)

التصميم 3

import androidx.compose.material3.Shapes

val AppShapes = Shapes(
    // M3 Shape parameters
)

ننصحك باستخدام عمليات الربط التالية للمَعلمات Shape كنقطة بدء:

التصميم 2 التصميم 3
لا ينطبق extraSmall
small small
medium medium
large large
لا ينطبق extraLarge

المكونات والتنسيقات

تتوفّر معظم المكوّنات والتنسيقات من الإصدار M2 في الإصدار M3. ومع ذلك، هناك بعض التقارير المفقودة بالإضافة إلى تقارير جديدة لم تكن متوفّرة في الإصدار M2. بالإضافة إلى ذلك، تحتوي بعض مكونات M3 على المزيد من الصيغ مقارنةً بنظيراتها في M2. بشكل عام، تحاول مساحات عرض واجهة برمجة التطبيقات في M3 أن تكون مشابهة قدر الإمكان لأقرب نظائرها في M2.

نظرًا لأنظمة الألوان والخطوط والأشكال المعدَّلة، تميل مكوّنات M3 إلى الربط بشكل مختلف بقيم المظهر الجديدة. ننصحك بالاطّلاع على directory الخاص بالرموز في رمز المصدر الخاص بتطبيق Compose Material 3 كمصدر للحصول على معلومات دقيقة عن عمليات الربط هذه.

على الرغم من أنّ بعض المكوّنات تتطلّب اعتبارات خاصة، ننصحك باستخدام عمليات ربط الدوال التالية كنقطة بداية:

واجهات برمجة التطبيقات غير المتوفّرة:

التصميم 2 التصميم 3
androidx.compose.material.swipeable غير متوفّر بعد

واجهات برمجة التطبيقات التي تم استبدالها:

التصميم 2 التصميم 3
androidx.compose.material.BackdropScaffold لا يتوفّر مكافئ لـ M3، لذا عليك نقل البيانات إلى Scaffold أو BottomSheetScaffold بدلاً من ذلك.
androidx.compose.material.BottomDrawer لا يتوفّر بديل لـ M3، لذا عليك نقل البيانات إلى ModalBottomSheet بدلاً من ذلك.

واجهات برمجة التطبيقات التي تمت إعادة تسميتها:

التصميم 2 التصميم 3
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

جميع واجهات برمجة التطبيقات الأخرى:

التصميم 2 التصميم 3
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

يمكنك الاطّلاع على أحدث مكونات وتنسيقات Material 3 في نظرة عامة على مرجع Compose Material 3 API، وننصحك بمتابعتنا في صفحة الإصدارات لمعرفة الواجهات الجديدة والمعدَّلة لواجهة برمجة التطبيقات.

الهيكل المؤقت وأشرطة التطبيقات المصغّرة ولوحة التنقّل

مقارنة بين إطار العمل M2 وM3 مع شريط التطبيقات المصغّرة ودرج التنقّل
الشكل 5. إطار عمل M2 مع شريط التطبيقات المصغّرة ودرج التنقل (على يمين الصفحة) مقارنةً بإطار عمل M3 مع شريط التطبيقات المصغّرة ودرج التنقل (على يمين الصفحة)

يختلف الهيكل في M3 عن الهيكل في M2. في كلّ من M2 وM3، يُطلق على العنصر القابل للتجميع في التنسيق الرئيسي اسم Scaffold، ولكن تختلف حِزم الاستيراد والمَعلمات:

التصميم 2

import androidx.compose.material.Scaffold

Scaffold(
    // M2 scaffold parameters
)

التصميم 3

import androidx.compose.material3.Scaffold

Scaffold(
    // M3 scaffold parameters
)

يحتوي النموذج M2 Scaffold على مَعلمة backgroundColor تمّ الآن تسميتها containerColor في النموذج M3 Scaffold:

التصميم 2

import androidx.compose.material.Scaffold

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

التصميم 3

import androidx.compose.material3.Scaffold

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

لم يعُد صف M2 ScaffoldState متوفّرًا في M3 لأنّه يحتوي على مَعلمة drawerState لم تعُد مطلوبة. لعرض أشرطة التطبيقات المصغّرة مع رمز M3 Scaffold، استخدِم SnackbarHostState بدلاً من ذلك:

التصميم 2

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

التصميم 3

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. لعرض درج يتضمّن رمز M3 Scaffold، استخدِم رمزًا قابلاً للتجميع لدرج التنقّل، مثل ModalNavigationDrawer، بدلاً من ذلك:

التصميم 2

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

التصميم 3

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 مع شريط التطبيقات العلوي والقائمة التي يتم التمرير فيها (على يمين الشاشة)

تختلف أشرطة التطبيقات العلوية في الإصدار 3 عن تلك الواردة في الإصدار 2. في كلّ من M2 وM3، يتمّ تسمية العنصر المُركّب الرئيسي لشريط التطبيقات العلوي باسم TopAppBar، ولكنّ حزم الوارد والمَعلمات تختلف:

التصميم 2

import androidx.compose.material.TopAppBar

TopAppBar(…)

التصميم 3

import androidx.compose.material3.TopAppBar

TopAppBar(…)

ننصحك باستخدام الرمز M3 CenterAlignedTopAppBar إذا كنت في السابق تُركز المحتوى داخل الرمز M2 TopAppBar. من المهم أيضًا معرفة MediumTopAppBar وLargeTopAppBar.

تحتوي أشرطة التطبيقات العلوية في M3 على مَعلمة scrollBehavior جديدة لتوفير وظائف مختلفة عند الانتقال للأسفل أو للأعلى في فئة TopAppBarScrollBehavior، مثل تغيير الارتفاع. ويمكن استخدام هذه الميزة مع الانتقال للأعلى أو للأسفل في المحتوى من خلال Modifer.nestedScroll. كان هذا ممكنًا في M2 TopAppBar من خلال تغيير المَعلمة elevation يدويًا:

التصميم 2

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) { … }
    }
)

التصميم 3

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:

التصميم 2

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

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

التصميم 3

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

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

الأزرار والأزرار التي تتضمّن رموزًا والأزرار المصغّرة للإجراءات السريعة

مقارنة بين زرَّي M2 وM3
الشكل 8. أزرار M2 (على يمين الشاشة) مقارنةً بأزرار M3 (على يمين الشاشة)

تختلف الأزرار وأزرار الرموز وأزرار الإجراءات العائمة في M3 عن تلك الواردة في M2. يتضمّن M3 جميع العناصر القابلة للتجميع لزر M2:

التصميم 2

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

التصميم 3

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 ولكنّ حِزم الاستيراد تختلف:

التصميم 2

import androidx.compose.material.Switch

Switch(…)

التصميم 3

import androidx.compose.material3.Switch

Switch(…)

الأسطح والارتفاع

مقارنة بين ارتفاع سطح M2 وارتفاع سطح M3 في المظهرَين الفاتح والداكن
الشكل 10. ارتفاع سطح M2 مقارنةً بارتفاع سطح M3 في الوضع الفاتح (على اليسار) والداكن (على اليمين).

تختلف أنظمة السطح والارتفاع في M3 عن M2. هناك نوعان من الإرتفاع في M3:

  • ارتفاع الظل (يلقي ظلًا، مثل M2)
  • الارتفاع التدرّجي للألوان (تتم إضافة لون جديد إلى M3)

في ميزة "الإنشاء"، ينطبق ذلك على دالة M2 Surface ودالة M3 Surface:

التصميم 2

import androidx.compose.material.Surface

Surface(
    elevation = …
) { … }

التصميم 3

import androidx.compose.material3.Surface

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

يمكنك استخدام قيم elevation Dp في M2 لكل من shadowElevation و/أو tonalElevation في M3، استنادًا إلى الإعدادات المفضّلة لتصميم تجربة المستخدم/واجهة المستخدم. Surface هو العنصر المكوّن الأساسي لمعظم المكوّنات، لذا قد تعرض مكونات المكوّنات أيضًا مَعلمات الارتفاع التي يجب نقلها بالطريقة نفسها.

يحلّ التأثير اللوني في الإصدار 3 محلّ مفهوم تراكب التأثيرات اللونية في المظهر الداكن للإصدار 2 . نتيجةً لذلك، لا يتوفّر ElevationOverlay وLocalElevationOverlay في الإصدار M3، وتم تغيير LocalAbsoluteElevation في الإصدار M2 إلى LocalAbsoluteTonalElevation في الإصدار M3.

تمييز المحتوى وتأثيره

مقارنة بين رمزَي M2 وM3 ونصهما المميّز
الشكل 11. رمز M2 وتمييز النص (على يمين الصفحة) مقارنةً برمز M3 وتمييز النص (على يمين الصفحة)

يختلف تركيز M3 عن تركيز M2 بشكل كبير. في M2، كان التأكيد يتضمن استخدام على الألوان مع قيم ألفا معيّنة للتمييز بين المحتوى مثل النص والرمز العميق. في الإصدار 3 من "إحصاءات YouTube"، تتوفّر الآن طريقتان مختلفتان:

  • استخدام ألوان مفعّلة إلى جانب ألوان متغيرة من نظام ألوان M3 الموسّع
  • استخدام كثافة خط مختلفة للنص

نتيجةً لذلك، لا يتوفّر ContentAlpha وLocalContentAlpha في M3 ويجب استبدالهما.

ننصحك باستخدام عمليات الربط التالية كنقطة بداية:

التصميم 2 التصميم 3
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:

التصميم 2

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

التصميم 3

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:

التصميم 2

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

التصميم 3

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 باستخدام القيم نفسها. مثلاً:

التصميم 2

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

التصميم 3

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

لمزيد من المعلومات حول نقل البيانات من M2 إلى M3 في Compose، يُرجى الرجوع إلى المراجع التالية الإضافية.

مستندات Google

أمثلة على التطبيقات

الفيديوهات

مرجع واجهة برمجة التطبيقات ورمز المصدر