إنشاء تنقُّل تكيُّفي

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

يبسّط NavigationSuiteScaffold التبديل بين واجهات المستخدم الخاصة بالتنقّل من خلال عرض واجهة المستخدم المناسبة والقابلة للإنشاء استنادًا إلى WindowSizeClass. ويشمل ذلك تغيير واجهة المستخدم ديناميكيًا أثناء تغييرات حجم النافذة في وقت التشغيل. يكون السلوك التلقائي هو عرض أيّ من مكوّنات واجهة المستخدم التالية:

  • شريط التنقّل إذا كان العرض أو الارتفاع مدمجَين أو إذا كان الجهاز في وضع على سطح مستوٍ
  • شريط التنقّل لكل العناصر الأخرى
الشكل 1. NavigationSuiteScaffold يعرض شريط تنقّل في النوافذ المصغّرة.
الشكل 2. يعرض "NavigationSuiteScaffold" شريط تنقُّل في النوافذ الموسّعة.

إضافة التبعيات

يمثّل NavigationSuiteScaffold جزءًا من مكتبة حزمة التنقّل التكيّفي في Material3. أضِف ملفًا ملحقًا للمكتبة في ملف build.gradle لتطبيقك أو وحدتك:

Kotlin


implementation("androidx.compose.material3:material3-adaptive-navigation-suite")

رائع


implementation 'androidx.compose.material3:material3-adaptive-navigation-suite'

إنشاء سقالة

الجزءان الرئيسيان من NavigationSuiteScaffold هما عناصر مجموعة التنقّل ومحتوى الوجهة المحدّدة. يمكنك تحديد عناصر مجموعة التنقّل مباشرةً في عنصر قابل للتجميع، ولكن من الشائع تحديد هذه العناصر في مكان آخر، على سبيل المثال، في قائمة أرقام مميزة:

enum class AppDestinations(
    @StringRes val label: Int,
    val icon: ImageVector,
    @StringRes val contentDescription: Int
) {
    HOME(R.string.home, Icons.Default.Home, R.string.home),
    FAVORITES(R.string.favorites, Icons.Default.Favorite, R.string.favorites),
    SHOPPING(R.string.shopping, Icons.Default.ShoppingCart, R.string.shopping),
    PROFILE(R.string.profile, Icons.Default.AccountBox, R.string.profile),
}

لاستخدام NavigationSuiteScaffold، عليك تتبُّع الوجهة الحالية، وهو ما يمكنك تنفيذه باستخدام rememberSaveable:

var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }

في المثال التالي، تستخدِم المَعلمة navigationSuiteItems (type NavigationSuiteScope) الدالة item لتحديد واجهة مستخدِم التنقّل لوجهة فردية. يتم استخدام واجهة مستخدم الوجهة في أشرطة التنقّل والقضبان والأدراج. لإنشاء عناصر التنقّل، عليك الانتقال إلى AppDestinations (المحدّد في المقتطف السابق):

NavigationSuiteScaffold(
    navigationSuiteItems = {
        AppDestinations.entries.forEach {
            item(
                icon = {
                    Icon(
                        it.icon,
                        contentDescription = stringResource(it.contentDescription)
                    )
                },
                label = { Text(stringResource(it.label)) },
                selected = it == currentDestination,
                onClick = { currentDestination = it }
            )
        }
    }
) {
    // TODO: Destination content.
}

في دالة lambda في محتوى الوجهة، استخدِم القيمة currentDestination لتحديد واجهة المستخدم التي تريد عرضها. إذا كنت تستخدم مكتبة تنقّل في تطبيقك، استخدِمها هنا لعرض الوجهة المناسبة. يمكن أن تكون عبارة when كافية في الحالات التالية:

NavigationSuiteScaffold(
    navigationSuiteItems = { /*...*/ }
) {
    // Destination content.
    when (currentDestination) {
        AppDestinations.HOME -> HomeDestination()
        AppDestinations.FAVORITES -> FavoritesDestination()
        AppDestinations.SHOPPING -> ShoppingDestination()
        AppDestinations.PROFILE -> ProfileDestination()
    }
}

تغيير الألوان

NavigationSuiteScaffold ينشئ Surface على المنطقة بالكامل التي يشغلها السقالة، عادةً النافذة الكاملة. بالإضافة إلى ذلك، يرسم الإطار الداعم واجهة مستخدم التنقل المحدّدة، مثل NavigationBar. يستخدم كلّ من واجهة مستخدِم السطح وواجهة مستخدِم التنقّل القيم المحدّدة في مظهر تطبيقك، ولكن يمكنك إلغاء قيم المظهر.

تحدّد المعلَمة containerColor لون السطح. اللون الافتراضي هو لون خلفية نظام الألوان لديك. تحدِّد المَعلمة contentColor لون المحتوى على هذه المساحة. الإعداد التلقائي هو اللون "مفعّل" لأيّ قيمة تم تحديدها لسمة containerColor. على سبيل المثال، إذا كان containerColor يستخدم اللون background، سيستخدم contentColor اللون onBackground. اطّلِع على استخدام مظاهر أسلوب Material Design 3 في تطبيق "الإنشاء" لمزيد من التفاصيل حول آلية عمل نظام الألوان. عند إلغاء هذه القيم، استخدِم القيم المحدّدة في المظهر ليتيح تطبيقك وضعَي شاشة ملفتة وملفتة للنظر:

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    containerColor = MaterialTheme.colorScheme.primary,
    contentColor = MaterialTheme.colorScheme.onPrimary,
) {
    // Content...
}

يتم رسم واجهة المستخدم للتنقّل في واجهة NavigationSuiteScaffold. يتم توفير القيم التلقائية للألوان في واجهة المستخدم من قِبل NavigationSuiteDefaults.colors()، ولكن بإمكانك إلغاء هذه القيم أيضًا. على سبيل المثال، إذا كنت تريد أن تكون خلفية شريط التنقّل شفافة ولكن القيم الأخرى هي التلقائية، يمكنك إلغاء navigationBarContainerColor:

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    navigationSuiteColors = NavigationSuiteDefaults.colors(
        navigationBarContainerColor = Color.Transparent,
    )
) {
    // Content...
}

في النهاية، يمكنك تخصيص كل عنصر في واجهة مستخدم التنقّل. عند استدعاء الدالة item، يمكنك تمرير مثيل من NavigationSuiteItemColors. تحدِّد الفئة ألوان العناصر في شريط التنقّل وشريط التنقّل ودرج التنقّل. وهذا يعني أنّه يمكنك استخدام ألوان متطابقة في كل نوع من أنواع واجهة مستخدم التنقّل، أو يمكنك تغيير الألوان استنادًا إلى احتياجاتك. حدِّد الألوان على مستوى NavigationSuiteScaffold لاستخدام مثيل العنصر نفسه لجميع العناصر واستخدِم الدالة NavigationSuiteDefaults.itemColors() لإلغاء الألوان التي تريد تغييرها فقط:

val myNavigationSuiteItemColors = NavigationSuiteDefaults.itemColors(
    navigationBarItemColors = NavigationBarItemDefaults.colors(
        indicatorColor = MaterialTheme.colorScheme.primaryContainer,
        selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer
    ),
)

NavigationSuiteScaffold(
    navigationSuiteItems = {
        AppDestinations.entries.forEach {
            item(
                icon = {
                    Icon(
                        it.icon,
                        contentDescription = stringResource(it.contentDescription)
                    )
                },
                label = { Text(stringResource(it.label)) },
                selected = it == currentDestination,
                onClick = { currentDestination = it },
                colors = myNavigationSuiteItemColors,
            )
        }
    },
) {
    // Content...
}

تخصيص أنواع التنقّل

يؤدي السلوك التلقائي في NavigationSuiteScaffold إلى تغيير واجهة المستخدم الخاصة بالتنقّل استنادًا إلى فئات حجم النوافذ. ومع ذلك، قد تحتاج إلى إلغاء هذا السلوك. على سبيل المثال، إذا كان تطبيقك يعرض جزءًا واحدًا كبيرًا من المحتوى لإحدى الخلاصات، يمكن للتطبيق استخدام درج تنقُّل دائم للنوافذ الموسّعة، ولكن مع ذلك يعود إلى السلوك التلقائي لفئات النوافذ الصغيرة والمتوسطة الحجم:

val adaptiveInfo = currentWindowAdaptiveInfo()
val customNavSuiteType = with(adaptiveInfo) {
    if (windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) {
        NavigationSuiteType.NavigationDrawer
    } else {
        NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo)
    }
}

NavigationSuiteScaffold(
    navigationSuiteItems = { /* ... */ },
    layoutType = customNavSuiteType,
) {
    // Content...
}

مصادر إضافية

اطّلِع على إرشادات التصميم المتعدد الأبعاد:

اطّلِع على مكوّنات مكتبة androidx.compose.material3 التالية: