اصول اولیه را درک و اجرا کنید

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

مدل سازی وضعیت ناوبری

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

یک دکمه عملکرد صفحه‌کلید نرم‌افزار (یک نماد علامت تیک) به رنگ قرمز دایره شده است.
شکل 1. نمودار نشان می دهد که چگونه پشته پشته با رویدادهای ناوبری کاربر تغییر می کند.

پشته پشتی ایجاد کنید

در Navigation 3، پشته پشتی در واقع حاوی محتوا نیست. در عوض، حاوی ارجاعاتی به محتوا است که به عنوان کلید شناخته می شود. کلیدها می توانند هر نوع باشند، اما معمولاً کلاس های داده ای ساده و قابل سریال سازی هستند. استفاده از منابع به جای محتوا دارای مزایای زیر است:

  • با فشار دادن کلیدها روی پشته، پیمایش آسان است.
  • تا زمانی که کلیدها قابل سریال‌سازی هستند، پشته پشتی را می‌توان در ذخیره‌سازی دائمی ذخیره کرد و به آن اجازه می‌دهد تا از تغییرات پیکربندی و مرگ پردازش جان سالم به در ببرد. این مهم است زیرا کاربران انتظار دارند برنامه شما را ترک کنند، بعداً به آن بازگردند و با نمایش محتوای مشابه از جایی که پایان دادند ادامه دهند. برای اطلاعات بیشتر به ذخیره پشته خود مراجعه کنید.

یک مفهوم کلیدی در Navigation 3 API این است که شما مالک پشته پشتی هستید. کتابخانه:

  • انتظار می رود که پشته پشته شما یک List<T> ، که در آن T نوع keys پشته شماست. می توانید از Any استفاده کنید یا می توانید کلیدهای خود را با تایپ قوی تر ارائه دهید. هنگامی که اصطلاحات "فشار" یا "پاپ" را می بینید، پیاده سازی اساسی این است که موارد را از انتهای یک لیست اضافه یا حذف کنید.
  • پشته شما را مشاهده می کند و وضعیت آن را در رابط کاربری با استفاده از NavDisplay منعکس می کند.

مثال زیر نحوه ایجاد کلیدها و پشته پشتی و اصلاح پشته پشتی در پاسخ به رویدادهای ناوبری کاربر را نشان می دهد:

// Define keys that will identify content
data object ProductList
data class ProductDetail(val id: String)

@Composable
fun MyApp() {

    // Create a back stack, specifying the key the app should start with
    val backStack = remember { mutableStateListOf<Any>(ProductList) }

    // Supply your back stack to a NavDisplay so it can reflect changes in the UI
    // ...more on this below...

    // Push a key onto the back stack (navigate forward), the navigation library will reflect the change in state
    backStack.add(ProductDetail(id = "ABC"))

    // Pop a key off the back stack (navigate back), the navigation library will reflect the change in state
    backStack.removeLastOrNull()
}

کلیدهای محتوا را حل کنید

محتوا در Navigation 3 با استفاده از NavEntry مدل‌سازی می‌شود که یک کلاس حاوی یک تابع قابل ترکیب است. این یک مقصد را نشان می دهد - یک تکه محتوا که کاربر می تواند به جلو و از آن برگردد .

NavEntry همچنین می‌تواند حاوی فراداده باشد - اطلاعاتی در مورد محتوا. این ابرداده را می توان توسط اشیاء کانتینری مانند NavDisplay خواند تا به آنها در تصمیم گیری در مورد نحوه نمایش محتوای NavEntry کمک کند. به عنوان مثال، ابرداده می تواند برای لغو انیمیشن های پیش فرض برای یک NavEntry خاص استفاده شود. metadata NavEntry نقشه‌ای از کلیدهای String برای Any مقدار است که ذخیره‌سازی داده‌های همه‌کاره را فراهم می‌کند.

برای تبدیل key به NavEntry ، یک entryProvider ایجاد کنید. این تابعی است که یک key می پذیرد و یک NavEntry برای آن key برمی گرداند. معمولاً هنگام ایجاد NavDisplay به عنوان پارامتر lambda تعریف می شود.

دو راه برای ایجاد یک entryProvider وجود دارد، یا با ایجاد یک تابع لامبدا به طور مستقیم، یا با استفاده از entryProvider DSL.

یک تابع entryProvider به طور مستقیم ایجاد کنید

شما معمولاً یک تابع entryProvider را با استفاده از دستور when ایجاد می‌کنید که برای هر یک از کلیدها یک شاخه وجود دارد.

entryProvider = { key ->
    when (key) {
        is ProductList -> NavEntry(key) { Text("Product List") }
        is ProductDetail -> NavEntry(
            key,
            metadata = mapOf("extraDataKey" to "extraDataValue")
        ) { Text("Product ${key.id} ") }

        else -> {
            NavEntry(Unit) { Text(text = "Invalid Key: $it") }
        }
    }
}

از entryProvider DSL استفاده کنید

entryProvider DSL می تواند عملکرد لامبدا شما را با اجتناب از نیاز به آزمایش در برابر هر یک از انواع کلید شما ساده کند و برای هر کدام یک NavEntry بسازد. برای این کار از تابع سازنده entryProvider استفاده کنید. همچنین شامل رفتار بازگشتی پیش فرض (پرتاب خطا) در صورت پیدا نشدن کلید است.

entryProvider = entryProvider {
    entry<ProductList> { Text("Product List") }
    entry<ProductDetail>(
        metadata = mapOf("extraDataKey" to "extraDataValue")
    ) { key -> Text("Product ${key.id} ") }
}

به موارد زیر از قطعه توجه کنید:

  • entry برای تعریف NavEntry با نوع داده شده و محتوای قابل ترکیب استفاده می شود
  • entry یک پارامتر metadata برای تنظیم NavEntry.metadata می پذیرد

پشته پشتی را نمایش دهید

پشته پشته نشان دهنده وضعیت پیمایش برنامه شما است. هر زمان که پشته پشتی تغییر کند، رابط کاربری برنامه باید وضعیت پشته جدید را منعکس کند. در Navigation 3، یک NavDisplay پشته شما را مشاهده می‌کند و UI خود را بر این اساس به‌روزرسانی می‌کند. آن را با پارامترهای زیر بسازید:

  • پشته شما - این باید از نوع SnapshotStateList<T> باشد که T نوع کلیدهای پشته شماست. این یک List قابل مشاهده است به طوری که وقتی NavDisplay تغییر می کند باعث ترکیب مجدد آن می شود.
  • یک entryProvider برای تبدیل کلیدهای پشته شما به NavEntry s.
  • به صورت اختیاری، یک لامبدا به پارامتر onBack ارائه دهید. این زمانی فراخوانی می شود که کاربر یک رویداد برگشتی را راه اندازی کند.

مثال زیر نحوه ایجاد NavDisplay را نشان می دهد.

data object Home
data class Product(val id: String)

@Composable
fun NavExample() {

    val backStack = remember { mutableStateListOf<Any>(Home) }

    NavDisplay(
        backStack = backStack,
        onBack = { backStack.removeLastOrNull() },
        entryProvider = { key ->
            when (key) {
                is Home -> NavEntry(key) {
                    ContentGreen("Welcome to Nav3") {
                        Button(onClick = {
                            backStack.add(Product("123"))
                        }) {
                            Text("Click to navigate")
                        }
                    }
                }

                is Product -> NavEntry(key) {
                    ContentBlue("Product ${key.id} ")
                }

                else -> NavEntry(Unit) { Text("Unknown route") }
            }
        }
    )
}

به‌طور پیش‌فرض، NavDisplay بالاترین NavEntry را در پشته پشتی در طرح‌بندی یک صفحه نمایش می‌دهد. ضبط زیر اجرای این برنامه را نشان می دهد:

رفتار پیش‌فرض «NavDisplay» با دو مقاصد
شکل 2. NavDisplay رفتار پیش فرض با دو مقصد.

همه را کنار هم گذاشتن

نمودار زیر نشان می دهد که چگونه داده ها بین اشیاء مختلف در Navigation 3 جریان می یابد:

تجسم نحوه جریان داده ها بین اشیاء مختلف در Navigation 3.
شکل 3. نمودار نشان می دهد که چگونه داده ها از طریق اشیاء مختلف در ناوبری 3 جریان می یابد.
  1. رویدادهای ناوبری تغییرات را آغاز می کنند . کلیدها در پاسخ به تعاملات کاربر از پشته اضافه یا حذف می شوند.

  2. تغییر در وضعیت پشته پشته بازیابی محتوا را آغاز می کند . NavDisplay (یک قابلیت ترکیب که پشته پشته را ارائه می کند) پشته پشتی را مشاهده می کند. در پیکربندی پیش‌فرض خود، بالاترین ورودی پشته پشته را در یک طرح‌بندی صفحه نمایش می‌دهد. هنگامی که کلید بالای پشته تغییر می کند، NavDisplay از این کلید برای درخواست محتوای مربوطه از ارائه دهنده ورودی استفاده می کند.

  3. ارائه دهنده ورودی محتوا را تامین می کند . ارائه دهنده ورودی تابعی است که کلید یک NavEntry را حل می کند. به محض دریافت کلید از NavDisplay ، ارائه‌دهنده ورودی NavEntry مرتبط را ارائه می‌کند که هم کلید و هم محتوا را در بر می‌گیرد.

  4. محتوا نمایش داده می شود . NavDisplay NavEntry را دریافت کرده و محتوا را نمایش می دهد.