نقل البيانات من Material 2.5 إلى Material 3 في تطبيق Compose لنظام التشغيل Wear OS

Material 3 Expressive هو الإصدار التالي من التصميم المتعدد الأبعاد. ويتضمن ذلك ميزات محدّثة للمظاهر والمكونات والتخصيص، مثل اللون الديناميكي.

يركّز هذا الدليل على نقل البيانات من مكتبة Jetpack‏ Wear Compose Material 2.5 (androidx.wear.compose) إلى مكتبة Jetpack‏ Wear Compose Material 3 (androidx.wear.compose.material3) للتطبيقات.

الأساليب

لنقل رمز تطبيقك من M2.5 إلى M3، اتّبِع النهج نفسه الموضّح في إرشادات نقل البيانات في Compose Material للهواتف، لا سيما:

الطلبات التابعة

يحتوي M3 على حزمة وإصدار منفصلين عن M2.5:

M2.5

implementation("androidx.wear.compose:compose-material:1.4.0")

التصميم 3

implementation("androidx.wear.compose:compose-material3:1.8.0-alpha03")

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

يقدّم الإصدار 1.8.0-alpha03 من مكتبة Wear Compose Foundation بعض المكوّنات الجديدة المصمّمة للعمل مع مكوّنات Material 3. وبالمثل، تم تعديل الحركة في SwipeDismissableNavHost من مكتبة Wear Compose Navigation عند تشغيلها على Wear OS 6 (مستوى واجهة برمجة التطبيقات 36) أو الإصدارات الأحدث. عند التحديث إلى الإصدار 3 من Wear Compose Material، ننصح أيضًا بتحديث مكتبتَي Wear Compose Foundation وNavigation:

implementation("androidx.wear.compose:compose-foundation:1.8.0-alpha03")
implementation("androidx.wear.compose:compose-navigation:1.8.0-alpha03")

المظهر

في كل من M2.5 وM3، يُطلق على الدالة المركّبة للمظهر اسم MaterialTheme، ولكن تختلف حِزم الاستيراد والمَعلمات. في M3، تمت إعادة تسمية المَعلمة Colors إلى ColorScheme وتم تقديم MotionScheme لتنفيذ عمليات الانتقال.

M2.5

import androidx.wear.compose.material.MaterialTheme

MaterialTheme(
    colors = AppColors,
    typography = AppTypography,
    shapes = AppShapes,
    content = content
)

التصميم 3

import androidx.wear.compose.material3.MaterialTheme
// ...
    MaterialTheme(
        colorScheme = ColorScheme(),
        typography = Typography(),
        shapes = Shapes(),
        motionScheme = MotionScheme.standard(),
        content = { /*content here*/ }
    )

اللون

يختلف نظام الألوان في M3 بشكل كبير عن M2.5. زاد عدد مَعلمات الألوان، وأصبحت لها أسماء مختلفة، ويتم ربطها بشكل مختلف بمكوّنات M3. في Compose، ينطبق ذلك على الفئة M2.5 Colors والفئة M3 ColorScheme والدوال ذات الصلة:

M2.5

import androidx.wear.compose.material.Colors

val appColorScheme: Colors = Colors(
   // M2.5 Color parameters
)

التصميم 3

import androidx.wear.compose.material3.ColorScheme
// ...
    val appColorScheme: ColorScheme = ColorScheme(
        // M3 ColorScheme parameters
    )

يوضّح الجدول التالي الاختلافات الرئيسية بين M2.5 وM3:

M2.5 التصميم 3
Colors تم تغيير الاسم إلى ColorScheme
‫13 لونًا ‫29 لونًا
لا ينطبق نسق الألوان الديناميكية الجديد
لا ينطبق ألوان ثالثية جديدة لمزيد من التعبير

نسق الألوان الديناميكية

من الميزات الجديدة في M3 نسق الألوان الديناميكي. إذا غيّر المستخدمون ألوان خلفية شاشة الساعة، تتغيّر الألوان في واجهة المستخدم لتتطابق معها.

استخدِم الدالة dynamicColorScheme لتطبيق نظام الألوان الديناميكية وقدِّم defaultColorScheme كخيار احتياطي في حال عدم توفّر نظام الألوان الديناميكية.

@Composable
fun myApp() {
    val dynamicColorScheme = dynamicColorScheme(LocalContext.current)
    MaterialTheme(colorScheme = dynamicColorScheme ?: myBrandColors) {}
}

internal val myBrandColors: ColorScheme = ColorScheme( /* Specify colors here */)

أسلوب الخط

يختلف نظام أسلوب الخط في M3 عن M2.5 ويتضمّن الميزات التالية:

  • تسعة أنماط نصية جديدة
  • الخطوط المرنة، والتي تتيح تخصيص مقاييس الخطوط للأوزان والعروض والاستدارة المختلفة
  • ‫AnimatedText، الذي يستخدم خطوطًا مرنة

M2.5

import androidx.wear.compose.material.Typography

val Typography = Typography(
   // M2.5 TextStyle parameters
)

التصميم 3

import androidx.wear.compose.material3.Typography

val Typography = Typography(
    // M3 TextStyle parameters
)

الخطوط المرنة

تتيح خطوط Flex للمصممين تحديد عرض الخط ووزنه لأحجام معينة.

أنماط النص

تتوفّر TextStyles التالية في M3. ويتم استخدامها تلقائيًا في مكوّنات M3 المختلفة.

أسلوب الخط TextStyle
الشاشة displayLarge, displayMedium, displaySmall
العنوان titleLarge, titleMedium, titleSmall
التصنيف labelLarge, labelMedium, labelSmall
Body bodyLarge, bodyMedium, bodySmall, bodyExtraSmall
عدد numeralExtraLarge, numeralLarge, numeralMedium, numeralSmall, numeralExtraSmall
قوس arcLarge, arcMedium, arcSmall

الشكل

يختلف نظام الأشكال في M3 عن M2.5. زاد عدد مَعلمات الأشكال، وتمت تسميتها بشكل مختلف، وتم ربطها بشكل مختلف بمكوّنات M3. تتوفّر أحجام الأشكال التالية:

  • صغيرة جدًا
  • صغير
  • متوسطة
  • كبير
  • كبير جدًا

في Compose، ينطبق ذلك على فئة M2.5 Shapes وفئة M3 Shapes:

M2.5

import androidx.wear.compose.material.Shapes

val Shapes = Shapes(
   // M2.5 Shapes parameters
)

التصميم 3

import androidx.wear.compose.material3.Shapes

val Shapes = Shapes(
    // M3 Shapes parameters
)

استخدِم تعيين مَعلمات الأشكال من Migrate من Material 2 إلى Material 3 في Compose كنقطة بداية.

تحويل الشكل

يقدّم M3 ميزة "تغيير الشكل" (Shape Morphing): تتغيّر الأشكال الآن استجابةً للتفاعلات.

يتوفّر سلوك "تغيير الشكل" كصيغة لعدد من الأزرار الدائرية، ويمكنك الاطّلاع على قائمة الأزرار التالية التي تتيح "تغيير الشكل":

الأزرار ميزة تحويل الأشكال
IconButton تُحرِّك IconButtonDefaults.animatedShapes زر الرمز عند الضغط عليه
IconToggleButton تُنشئ السمة IconToggleButtonDefaults.animatedShapes تأثيرًا متحركًا لزر الإيقاف/التفعيل الذي يتضمّن رمزًا عند الضغط عليه، بينما تُنشئ السمة
IconToggleButtonDefaults.variantAnimatedShapes تأثيرًا متحركًا لزر الإيقاف/التفعيل الذي يتضمّن رمزًا عند الضغط عليه ووضع علامة في المربّع أو إزالتها
TextButton تُحرِّك السمة TextButtonDefaults.animatedShapes الزر النصي عند الضغط عليه
TextToggleButton تُحرِّك السمة TextToggleButtonDefaults.animatedShapes زر تبديل النص عند الضغط عليه، بينما تُحرِّك السمة TextToggleButtonDefaults.variantAnimatedShapes زر تبديل النص عند الضغط عليه ووضع علامة في المربّع أو إزالتها

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

تتوفّر معظم المكوّنات والتنسيقات من M2.5 في M3. ومع ذلك، لم تكن بعض مكوّنات وتنسيقات M3 متوفّرة في M2.5. علاوة على ذلك، تحتوي بعض مكونات M3 على اختلافات أكثر من نظيراتها في M2.5.

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

Material 2.5 Material 3
androidx.wear.compose.material.dialog.Alert androidx.wear.compose.material3.AlertDialog
androidx.wear.compose.material.Button ‫androidx.wear.compose.material3.IconButton أو androidx.wear.compose.material3.TextButton
androidx.wear.compose.material.Card androidx.wear.compose.material3.Card
androidx.wear.compose.material.TitleCard androidx.wear.compose.material3.TitleCard
androidx.wear.compose.material.AppCard androidx.wear.compose.material3.AppCard
androidx.wear.compose.material.Checkbox لا يتوفّر مكافئ في M3، لذا عليك نقل البيانات إلى androidx.wear.compose.material3.CheckboxButton أو androidx.wear.compose.material3.SplitCheckboxButton
androidx.wear.compose.material.Chip ‫androidx.wear.compose.material3.Button أو
androidx.wear.compose.material3.OutlinedButton أو
androidx.wear.compose.material3.FilledTonalButton أو
androidx.wear.compose.material3.ChildButton
androidx.wear.compose.material.CompactChip androidx.wear.compose.material3.CompactButton
androidx.wear.compose.material.InlineSlider androidx.wear.compose.material3.Slider
androidx.wear.compose.material.LocalContentAlpha() تمت إزالة هذا المكوّن لأنّه غير مستخدَم من قِبل Text أو Icon في Material 3
androidx.wear.compose.material.PositionIndicator androidx.wear.compose.material3.ScrollIndicator
androidx.wear.compose.material.RadioButton لا يتوفّر مكافئ في M3، لذا عليك نقل البيانات إلى androidx.wear.compose.material3.RadioButton أو androidx.wear.compose.material3.SplitRadioButton
androidx.wear.compose.material.SwipeToRevealCard androidx.wear.compose.material3.SwipeToReveal
androidx.wear.compose.material.SwipeToRevealChip androidx.wear.compose.material3.SwipeToReveal
androidx.wear.compose.material.Scaffold androidx.wear.compose.material3.AppScaffold وandroidx.wear.compose.material3.ScreenScaffold
androidx.wear.compose.material.SplitToggleChip لا يتوفّر مكافئ في M3، لذا عليك نقل البيانات إلى androidx.wear.compose.material3.SplitCheckboxButton أو androidx.wear.compose.material3.SplitSwitchButton أو androidx.wear.compose.material3.SplitRadioButton
androidx.wear.compose.material.Switch لا يتوفّر مكافئ في M3، لذا عليك نقل البيانات إلى androidx.wear.compose.material3.SwitchButton أو androidx.wear.compose.material3.SplitSwitchButton
androidx.wear.compose.material.ToggleButton ‫androidx.wear.compose.material3.IconToggleButton أو androidx.wear.compose.material3.TextToggleButton
androidx.wear.compose.material.ToggleChip androidx.wear.compose.material3.CheckboxButton أو
androidx.wear.compose.material3.RadioButton أو
androidx.wear.compose.material3.SwitchButton
androidx.wear.compose.material.Vignette تمت إزالتها لأنّها غير مضمّنة في تصميم Material 3 Expressive لنظام التشغيل Wear OS

في ما يلي قائمة بمكوّنات Material 3 الشائعة وما يعادلها في Material 2.5:

Material 3 المكوّن المكافئ في Material 2.5 (إذا لم يكن جديدًا في M3)
androidx.wear.compose.material3.AlertDialog androidx.wear.compose.material.dialog.Alert
androidx.wear.compose.material3.AnimatedPage جديد
androidx.wear.compose.material3.AnimatedText جديد
androidx.wear.compose.material3.AppScaffold androidx.wear.compose.material.Scaffold (باستخدام androidx.wear.compose.material3.ScreenScaffold)
androidx.wear.compose.material3.Button androidx.wear.compose.material.Chip
androidx.wear.compose.material3.ButtonGroup جديد
androidx.wear.compose.material3.Card androidx.wear.compose.material.Card
androidx.wear.compose.material3.CheckboxButton androidx.wear.compose.material.ToggleChip مع عنصر تحكّم في تبديل مربّع الاختيار
androidx.wear.compose.material3.ChildButton ‫androidx.wear.compose.material.Chip (فقط في حال عدم الحاجة إلى خلفية)
androidx.wear.compose.material3.CircularProgressIndicator androidx.wear.compose.material.CircularProgressIndicator
androidx.wear.compose.material3.CompactButton androidx.wear.compose.material.CompactChip
androidx.wear.compose.material3.ConfirmationDialog androidx.wear.compose.material.dialog.Confirmation
androidx.wear.compose.material3.curvedText androidx.wear.compose.material.curvedText
androidx.wear.compose.material3.DatePicker جديد
androidx.wear.compose.material3.Dialog androidx.wear.compose.material.dialog.Dialog
androidx.wear.compose.material3.EdgeButton جديد
androidx.wear.compose.material3.FadingExpandingLabel جديد
androidx.wear.compose.material3.FilledTonalButton ‫androidx.wear.compose.material.Chip عندما تكون خلفية الزر بلون واحد مطلوبة
androidx.wear.compose.material3.HorizontalPageIndicator androidx.wear.compose.material.HorizontalPageIndicator
androidx.wear.compose.material3.HorizontalPagerScaffold جديد
androidx.wear.compose.material3.Icon androidx.wear.compose.material.Icon
androidx.wear.compose.material3.IconButton androidx.wear.compose.material.Button
androidx.wear.compose.material3.IconToggleButton androidx.wear.compose.material.ToggleButton
androidx.wear.compose.material3.LevelIndicator جديد
androidx.wear.compose.material3.LinearProgressIndicator جديد
androidx.wear.compose.material3.ListHeader androidx.wear.compose.material.ListHeader
androidx.wear.compose.material3.ListSubHeader جديد
androidx.wear.compose.material3.MaterialTheme androidx.wear.compose.material.MaterialTheme
androidx.wear.compose.material3.OpenOnPhoneDialog جديد
androidx.wear.compose.material3.Picker androidx.wear.compose.material.Picker
androidx.wear.compose.material3.PickerGroup androidx.wear.compose.material.PickerGroup
androidx.wear.compose.material3.RadioButton ‫androidx.wear.compose.material.ToggleChip مع عنصر تحكّم في زر الاختيار
androidx.wear.compose.material3.ScreenScaffold androidx.wear.compose.material.Scaffold (باستخدام androidx.wear.compose.material3.AppScaffold)
androidx.wear.compose.material3.ScrollIndicator androidx.wear.compose.material.PositionIndicator
androidx.wear.compose.material3.scrollAway androidx.wear.compose.material.scrollAway
androidx.wear.compose.material3.SegmentedCircularProgressIndicator جديد
androidx.wear.compose.material3.Slider androidx.wear.compose.material.InlineSlider
androidx.wear.compose.material3.SplitRadioButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.SplitCheckboxButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.SplitSwitchButton androidx.wear.compose.material.SplitToggleChip
androidx.wear.compose.material3.Stepper androidx.wear.compose.material.Stepper
androidx.wear.compose.material3.SwipeToDismissBox androidx.wear.compose.material.SwipeToDismissBox
androidx.wear.compose.material3.SwipeToReveal androidx.wear.compose.material.SwipeToRevealCard وandroidx.wear.compose.material.SwipeToRevealChip
androidx.wear.compose.material3.SwitchButton ‫androidx.wear.compose.material.ToggleChip مع عنصر تحكّم في مفتاح التبديل
androidx.wear.compose.material3.Text androidx.wear.compose.material.Text
androidx.wear.compose.material3.TextButton androidx.wear.compose.material.Button
androidx.wear.compose.material3.TextToggleButton androidx.wear.compose.material.ToggleButton
androidx.wear.compose.material3.TimeText androidx.wear.compose.material.TimeText
androidx.wear.compose.material3.VerticalPagerScaffold جديد

وأخيرًا، إليك قائمة ببعض المكوّنات ذات الصلة من مكتبة Wear Compose Foundation:

الإصدار 1.8.0‎-alpha03 من Wear Compose Foundation
androidx.wear.compose.foundation.hierarchicalFocusGroup يُستخدَم لإضافة تعليقات توضيحية إلى الدوال المركّبة في أحد التطبيقات، وذلك لتتبُّع الجزء النشط من التركيب وتنسيق التركيز.
androidx.wear.compose.foundation.pager.HorizontalPager هو عنصر تنقّل بين الصفحات يتم تمريره أفقيًا، ويستند إلى مكوّنات Compose Foundation مع تحسينات خاصة بالأجهزة القابلة للارتداء لتحسين الأداء والالتزام بإرشادات Wear OS.
androidx.wear.compose.foundation.pager.VerticalPager هو أداة تنقّل بين الصفحات بشكل عمودي، تم إنشاؤها استنادًا إلى مكوّنات Compose Foundation مع تحسينات مخصّصة لأجهزة Wear لتحسين الأداء والالتزام بإرشادات Wear OS.
androidx.wear.compose.foundation.lazy.TransformingLazyColumn يمكن استخدامها بدلاً من ScalingLazyColumn لإضافة تأثيرات تحويل التمرير إلى كل عنصر.

الأزرار

تختلف الأزرار في M3 عن M2.5. تم استبدال شريحة M2.5 بالزر. Button implementation provides default values for Text maxLines and textAlign. ويمكن إلغاء هذه القيم التلقائية في العنصر Text.

M2.5

import androidx.wear.compose.material.Chip

//M2.5 Buttons
Chip(...)
CompactChip(...)
Button(...)

التصميم 3

//M3 Buttons
Button(onClick = { }){}
CompactButton(onClick = { }){}
IconButton(onClick = { }){}
TextButton(onClick = { }){}

يتضمّن M3 أيضًا أشكالاً جديدة للأزرار. يمكنك الاطّلاع عليها في نظرة عامة على مرجع واجهة برمجة التطبيقات Compose Material 3.

يقدّم الإصدار M3 زرًا جديدًا: EdgeButton. يتوفّر "EdgeButton" بأربعة مقاسات مختلفة: صغير جدًا وصغير ومتوسط وكبير. EdgeButton implementation provide a default value for maxLines depending on the size which can be customized.

إذا كنت تستخدم TransformingLazyColumn أو ScalingLazyColumn، يمكنك تمرير EdgeButton إلى ScreenScaffold ليتغيّر شكله مع الانتقال للأعلى أو للأسفل، بدلاً من إضافة EdgeButton كعنصر القائمة الأخير. يُرجى الاطّلاع على الرمز التالي لمعرفة كيفية استخدام EdgeButton مع ScreenScaffold وTransformingLazyColumn.

val state = rememberTransformingLazyColumnState()
ScreenScaffold(
    scrollState = state,
    edgeButton = {
        EdgeButton(
            onClick = { },
            modifier = Modifier.scrollable(
                state,
                orientation = Orientation.Vertical,
                reverseDirection = true,
                // Apply overscroll to the EdgeButton for proper scrolling behavior.
                overscrollEffect = rememberOverscrollEffect(),
            ),
        ) {
            Text(stringResource(R.string.show))
        }
    },
) { contentPadding ->
    TransformingLazyColumn(state = state, contentPadding = contentPadding) {
        // additional code here
        // ...
    }
}

Scaffold

يختلف Scaffold في M3 عن M2.5. في M3، تم استبدال Scaffold بـ AppScaffold والدالة المركّبة الجديدة ScreenScaffold. يحدّد AppScaffold وScreenScaffold بنية الشاشة وينسّقان عمليات الانتقال بين مكوّنات ScrollIndicator وTimeText.

يسمح AppScaffold لعناصر الشاشة الثابتة، مثل TimeText، بالبقاء مرئية أثناء عمليات الانتقال داخل التطبيق، مثل التمرير السريع للإغلاق. ويوفّر مساحة لمحتوى التطبيق الرئيسي، والذي يتم توفيره عادةً من خلال مكوّن تنقّل مثل SwipeDismissableNavHost

يمكنك تحديد AppScaffold واحد لكل نشاط واستخدام ScreenScaffold لكل شاشة. يضيف AppScaffold مكوّن TimeText تلقائيًا إلى الشاشات. ويمكنك تجاوزها إذا أردت تخصيصها باستخدام المَعلمة timeText.

M2.5

import androidx.wear.compose.material.Scaffold

Scaffold {...}

التصميم 3

    AppScaffold {
        val navController = rememberSwipeDismissableNavController()
        SwipeDismissableNavHost(
            navController = navController,
            startDestination = "message_list"
        ) {
            composable("message_list") {
                MessageList(onMessageClick = { id ->
                    navController.navigate("message_detail/$id")
                })
            }
            composable("message_detail/{id}") {
                MessageDetail(id = it.arguments?.getString("id")!!)
            }
        }
    }
}

// Implementation of one of the screens in the navigation
@Composable
fun MessageDetail(id: String) {
    // .. Screen level content goes here
    val scrollState = rememberTransformingLazyColumnState()
    val transformationSpec = rememberTransformationSpec()

    ScreenScaffold(
        scrollState = scrollState,
    ) { contentPadding ->
        // Screen content goes here
        // ...

إذا كنت تستخدم HorizontalPager مع HorizontalPageIndicator، يمكنك نقل البيانات إلى HorizontalPagerScaffold. يتم وضع HorizontalPagerScaffold ضمن AppScaffold. يحدّد AppScaffold وHorizontalPagerScaffold بنية "التنقّل بين الصفحات" وينسّقان عمليات الانتقال بين مكوّنات HorizontalPageIndicator وTimeText.

يعرض HorizontalPagerScaffold HorizontalPageIndicator في منتصف نهاية الشاشة تلقائيًا وينسّق عرض وإخفاء TimeText وHorizontalPageIndicator وفقًا لما إذا كان Pager يتم التنقّل بين صفحاته، ويتم تحديد ذلك من خلال PagerState.

هناك أيضًا مكوّن AnimatedPage جديد يحرّك صفحة ضمن "التنقّل بين الصفحات" مع تأثير تغيير الحجم والتعتيم استنادًا إلى موضعها.

AppScaffold {
    val pagerState = rememberPagerState(pageCount = { 10 })

    HorizontalPagerScaffold(pagerState = pagerState) {
        HorizontalPager(
            state = pagerState,
            flingBehavior =
                PagerScaffoldDefaults.snapWithSpringFlingBehavior(
                    state = pagerState
                ),
        ) { page ->
            AnimatedPage(pageIndex = page, pagerState = pagerState) {
                val columnState = rememberTransformingLazyColumnState()
                val transformationSpec = rememberTransformationSpec()

                ScreenScaffold(
                    scrollState = columnState,
                ) { contentPadding ->
                    TransformingLazyColumn(
                        state = columnState,
                        contentPadding = contentPadding,
                    ) {
                        item {
                            ListHeader(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .transformedHeight(this, transformationSpec)
                                    .minimumVerticalContentPadding(
                                        ListHeaderDefaults.minimumTopListContentPadding
                                    ),
                                transformation = SurfaceTransformation(transformationSpec),
                            ) {
                                Text(text = "Pager sample")
                            }
                        }
                        item {
                            Card(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .transformedHeight(this, transformationSpec)
                                    .minimumVerticalContentPadding(
                                        CardDefaults.minimumVerticalListContentPadding
                                    ),
                                transformation = SurfaceTransformation(transformationSpec),
                            ) {
                                if (page == 0) {
                                    Text(text = "Page #$page. Swipe right")
                                } else {
                                    Text(text = "Page #$page. Swipe left and right")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

أخيرًا، يقدّم M3 مكوّن VerticalPagerScaffold الذي يتّبع النمط نفسه الذي يتّبعه HorizontalPagerScaffold:

@Composable
fun VerticalPagerScaffoldSample() {
    AppScaffold {
        val pagerState = rememberPagerState(pageCount = { 10 })

        VerticalPagerScaffold(pagerState = pagerState) {
            VerticalPager(
                state = pagerState,
                flingBehavior =
                    PagerScaffoldDefaults.snapWithSpringFlingBehavior(
                        state = pagerState
                    ),
            ) { page ->
                AnimatedPage(pageIndex = page, pagerState = pagerState) {
                    ScreenScaffold {
                        Column(
                            modifier = Modifier.fillMaxSize(),
                            horizontalAlignment = Alignment.CenterHorizontally,
                            verticalArrangement = Arrangement.Center,
                        ) {
                            Text(text = "Page #$page")
                            Spacer(modifier = Modifier.height(8.dp))
                            Text(text = "Swipe up and down")
                        }
                    }
                }
            }
        }
    }
}

عنصر نائب

هناك بعض التغييرات في واجهة برمجة التطبيقات بين الإصدارين M2.5 وM3. يوفر M3 معدّلين للعناصر النائبة:

  • Modifier.placeholder، الذي يتم رسمه بدلاً من المحتوى الذي لم يتم تحميله بعد
  • تأثير وميض العنصر النائب Modifier.placeholderShimmer الذي يوفّر تأثير وميض العنصر النائب الذي يتم تشغيله في حلقة رسوم متحركة أثناء انتظار تحميل البيانات.

اطّلِع على الجدول التالي لمعرفة التغييرات الإضافية التي تم إجراؤها على مكوّن Placeholder.

M2.5 التصميم 3
PlaceholderState.startPlaceholderAnimation تمت إزالته
PlaceholderState.placeholderProgression تمت إزالته
PlaceholderState.isShowContent تم استبداله بـ PlaceholderState.isVisible (قيمة منطقية معكوسة)
PlaceholderState.isWipeOff تمت إزالته
PlaceholderDefaults.painterWithPlaceholderOverlayBackgroundBrush تمت إزالته
PlaceholderDefaults.placeholderBackgroundBrush تمت إزالته
PlaceholderDefaults.placeholderChipColors تمت إزالته

SwipeDismissableNavHost

‫"SwipeDismissableNavHost" هو جزء من "wear.compose.navigation". عند استخدام هذا المكوّن مع M3، يحدّث M3 MaterialTheme السمتَين LocalSwipeToDismissBackgroundScrimColor وLocalSwipeToDismissContentScrimColor.

TransformingLazyColumn

‫TransformingLazyColumn هي جزء من androidx.wear.compose.foundation.lazy وتضيف دعمًا لتغيير حجم الصور المتحركة وتحويلها في عناصر القائمة أثناء التمرير، ما يحسّن تجربة المستخدم. ننصح بشدة بنقل التطبيقات من ScalingLazyColumn إلى TransformingLazyColumn.

على غرار ScalingLazyColumn، يوفّر rememberTransformingLazyColumnState() لإنشاء TransformingLazyColumnState يتم تذكّره في جميع العناصر القابلة للإنشاء.

لإضافة تأثيرات حركية لتغيير الحجم والتحويل، أضِف ما يلي إلى كل عنصر في القائمة:

  • Modifier.transformedHeight، التي تتيح لك حساب الارتفاع المحوَّل للعناصر باستخدام TransformationSpec، يمكنك استخدام rememberTransformationSpec() ما لم تكن بحاجة إلى مزيد من التخصيص.
  • SurfaceTransformation

للتحقّق من صحة المساحة المتروكة في أعلى القائمة وأسفلها، استخدِم المُعدِّل minimumVerticalContentPadding.

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(
    scrollState = columnState
) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding
    ) {
        item {
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        imageVector = Icons.Default.Build,
                        contentDescription = "build",
                    )
                },
            ) {
                Text(
                    text = "Build",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
    }
}

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

نماذج

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

تصميم