ایجاد ناوبری تطبیقی

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

NavigationSuiteScaffold با نمایش رابط کاربری ناوبری مناسب که بر اساس WindowSizeClass قابل ترکیب است، جابجایی بین رابط‌های کاربری ناوبری را ساده می‌کند. این شامل تغییر پویای رابط کاربری در طول تغییر اندازه پنجره در زمان اجرا می‌شود. رفتار پیش‌فرض نمایش هر یک از اجزای رابط کاربری زیر است:

  • نوار ناوبری اگر عرض یا ارتفاع جمع و جور باشد یا اگر دستگاه در حالت رومیزی باشد
  • ریل ناوبری برای هر چیز دیگری
شکل ۱. NavigationSuiteScaffold یک نوار ناوبری را در پنجره‌های فشرده نمایش می‌دهد.
شکل ۲. NavigationSuiteScaffold یک ریل ناوبری را در پنجره‌های باز شده نمایش می‌دهد.

وابستگی‌ها را اضافه کنید

NavigationSuiteScaffold بخشی از کتابخانه‌ی مجموعه‌ی ناوبری تطبیقی ​​Material3 است. یک وابستگی برای کتابخانه در فایل build.gradle برنامه یا ماژول خود اضافه کنید:

کاتلین

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

گرووی

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

یک داربست ایجاد کنید

دو بخش اصلی NavigationSuiteScaffold آیتم‌های مجموعه ناوبری و محتوای مقصد انتخاب شده هستند. می‌توانید آیتم‌های مجموعه ناوبری را مستقیماً در یک composable تعریف کنید، اما معمولاً این موارد در جای دیگری، مثلاً در یک enum، تعریف می‌شوند:

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 (از نوع 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.
}

درون محتوای مقصد لامبدا، از مقدار currentDestination برای تصمیم‌گیری در مورد نمایش رابط کاربری استفاده کنید. اگر از یک کتابخانه ناوبری در برنامه خود استفاده می‌کنید، از آن در اینجا برای نمایش مقصد مناسب استفاده کنید. یک عبارت when می‌تواند کافی باشد:

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

تغییر رنگ‌ها

NavigationSuiteScaffold یک Surface روی کل ناحیه‌ای که scaffold اشغال می‌کند، معمولاً کل پنجره، ایجاد می‌کند. علاوه بر آن، scaffold رابط کاربری ناوبری خاص، مانند NavigationBar را ترسیم می‌کند. هم سطح و هم رابط کاربری ناوبری از مقادیر مشخص شده در تم برنامه شما استفاده می‌کنند، اما می‌توانید مقادیر تم را لغو کنید.

پارامتر containerColor رنگ سطح را مشخص می‌کند. پیش‌فرض، رنگ پس‌زمینه طرح رنگی شماست. پارامتر contentColor رنگ محتوای روی آن سطح را مشخص می‌کند. پیش‌فرض، رنگ "روشن" هر چیزی است که برای containerColor مشخص شده است. برای مثال، اگر containerColor از رنگ background استفاده می‌کند، contentColor از رنگ onBackground استفاده می‌کند. برای جزئیات بیشتر در مورد نحوه عملکرد سیستم رنگ، به تم‌بندی Material Design 3 در Compose مراجعه کنید. هنگام بازنویسی این مقادیر، از مقادیر تعریف شده در تم خود استفاده کنید تا برنامه شما از حالت‌های نمایش تیره و روشن پشتیبانی کند:

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.isWidthAtLeastBreakpoint(WIDTH_DP_EXPANDED_LOWER_BOUND)) {
        NavigationSuiteType.NavigationDrawer
    } else {
        NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo)
    }
}

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

منابع اضافی