یک چیدمان فهرست با جزئیات بسازید

List-detail یک الگوی رابط کاربری است که از یک طرح‌بندی دو قسمتی تشکیل شده است که در آن یک قسمت لیستی از موارد را ارائه می‌دهد و قسمت دیگر جزئیات موارد انتخاب شده از لیست را نمایش می‌دهد.

این الگو به ویژه برای برنامه‌هایی مفید است که اطلاعات عمیقی در مورد عناصر مجموعه‌های بزرگ ارائه می‌دهند، به عنوان مثال، یک سرویس گیرنده ایمیل که لیستی از ایمیل‌ها و محتوای دقیق هر پیام ایمیل را دارد. List-detail همچنین می‌تواند برای مسیرهای کم‌اهمیت‌تر مانند تقسیم تنظیمات برنامه به لیستی از دسته‌ها با تنظیمات مربوط به هر دسته در قسمت جزئیات استفاده شود.

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

الگوی List-Detail را با NavigableListDetailPaneScaffold پیاده‌سازی کنید

NavigableListDetailPaneScaffold یک composable است که پیاده‌سازی طرح‌بندی list-detail را در Jetpack Compose ساده می‌کند. این ListDetailPaneScaffold را در بر می‌گیرد و ناوبری داخلی و انیمیشن‌های پیش‌بینی‌کننده‌ی بازگشت را اضافه می‌کند.

یک داربست لیست-جزئیات تا سه پنل را پشتیبانی می‌کند:

  1. پنجره فهرست : مجموعه‌ای از اقلام را نمایش می‌دهد.
  2. پنل جزئیات : جزئیات یک آیتم انتخاب شده را نشان می‌دهد.
  3. صفحه اضافی ( اختیاری ) : در صورت نیاز، زمینه اضافی ارائه می‌دهد.

داربست بر اساس اندازه پنجره تنظیم می‌شود:

  • در پنجره‌های بزرگ، فهرست و جزئیات در کنار هم نمایش داده می‌شوند.
  • در پنجره‌های کوچک، فقط یک پنل در هر زمان قابل مشاهده است و با پیمایش کاربران، پنل‌ها تغییر می‌کنند.

اعلان وابستگی‌ها

NavigableListDetailPaneScaffold بخشی از کتابخانه ناوبری تطبیقی ​​Material 3 است.

سه وابستگی مرتبط زیر را به فایل build.gradle برنامه یا ماژول خود اضافه کنید:

کاتلین

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

گرووی

implementation 'androidx.compose.material3.adaptive:adaptive'
implementation 'androidx.compose.material3.adaptive:adaptive-layout'
implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
  • تطبیقی: بلوک‌های سازنده سطح پایین مانند HingeInfo و Posture
  • adaptive-layout: طرح‌بندی‌های تطبیقی ​​مانند ListDetailPaneScaffold و SupportingPaneScaffold
  • adaptive-navigation: کامپوننت‌هایی برای پیمایش درون و بین پنل‌ها، و همچنین طرح‌بندی‌های تطبیقی ​​که به طور پیش‌فرض از پیمایش پشتیبانی می‌کنند مانند NavigableListDetailPaneScaffold و NavigableSupportingPaneScaffold

مطمئن شوید که پروژه شما شامل compose-material3-adaptive نسخه ۱.۱.۰-beta1 یا بالاتر است.

از ژست حرکتی پیش‌بینی‌کننده‌ی بازگشت استفاده کنید

برای فعال کردن انیمیشن‌های پیش‌بینی‌کننده‌ی بازگشت در اندروید ۱۵ یا پایین‌تر، باید پشتیبانی از ژست پیش‌بینی‌کننده‌ی بازگشت را انتخاب کنید. برای انتخاب، android:enableOnBackInvokedCallback="true" به تگ <application> یا تگ‌های <activity> جداگانه در فایل AndroidManifest.xml خود اضافه کنید. برای اطلاعات بیشتر، به بخش «انتخاب ژست پیش‌بینی‌کننده‌ی بازگشت» مراجعه کنید.

زمانی که برنامه شما اندروید ۱۶ (سطح API ۳۶) یا بالاتر را هدف قرار می‌دهد، پیش‌بینی بازگشت به طور پیش‌فرض فعال می‌شود.

کاربرد اولیه

NavigableListDetailPaneScaffold به صورت زیر پیاده‌سازی کنید:

  1. از کلاسی استفاده کنید که محتوای انتخاب شده را نشان می‌دهد. از کلاس Parcelable برای پشتیبانی از ذخیره و بازیابی آیتم لیست انتخاب شده استفاده کنید. از افزونه kotlin-parcelize برای تولید کد برای خود استفاده کنید.
  2. یک ThreePaneScaffoldNavigator با rememberListDetailPaneScaffoldNavigator ایجاد کنید.

این ناوبر برای حرکت بین لیست، جزئیات و پنل‌های اضافی استفاده می‌شود. با تعریف یک نوع عمومی، ناوبر وضعیت scaffold (یعنی اینکه کدام MyItem نمایش داده می‌شود) را نیز ردیابی می‌کند. از آنجایی که این نوع قابل دسته‌بندی است، ناوبر می‌تواند وضعیت را ذخیره و بازیابی کند تا به طور خودکار تغییرات پیکربندی را مدیریت کند.

  1. ناویگاتور را به ترکیب‌بندی NavigableListDetailPaneScaffold ارسال کنید.

  2. پیاده‌سازی صفحه لیست خود را به NavigableListDetailPaneScaffold ارائه دهید. از AnimatedPane برای اعمال انیمیشن‌های پیش‌فرض صفحه در حین پیمایش استفاده کنید. سپس از ThreePaneScaffoldNavigator برای پیمایش به صفحه جزئیات، ListDetailPaneScaffoldRole.Detail ، و نمایش آیتم ارسالی استفاده کنید.

  3. پیاده‌سازی صفحه جزئیات خود را در NavigableListDetailPaneScaffold لحاظ کنید.

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

  1. به صورت اختیاری، defaultBackBehavior در NavigableListDetailPaneScaffold تغییر دهید. به طور پیش‌فرض، NavigableListDetailPaneScaffold از PopUntilScaffoldValueChange برای defaultBackBehavior استفاده می‌کند.

اگر برنامه شما به الگوی ناوبری برگشتی متفاوتی نیاز دارد، می‌توانید با تعیین یک گزینه BackNavigationBehavior دیگر، این رفتار را لغو کنید.

گزینه های BackNavigationBehavior

بخش زیر از مثال یک برنامه ایمیل با لیستی از ایمیل‌ها در یک پنل و نمای تفصیلی در پنل دیگر استفاده می‌کند.

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

به مثال‌های زیر توجه کنید:

  • چند صفحه‌ای: شما در حال مشاهده یک ایمیل (مورد ۱) در صفحه جزئیات هستید. کلیک روی ایمیل دیگری (مورد ۲) صفحه جزئیات را به‌روزرسانی می‌کند، اما فهرست و صفحات جزئیات همچنان قابل مشاهده هستند. فشردن دکمه بازگشت ممکن است از برنامه یا جریان پیمایش فعلی خارج شود.
  • تک‌صفحه‌ای: ابتدا مورد ۱ و سپس مورد ۲ را مشاهده می‌کنید، فشردن دکمه بازگشت شما را مستقیماً به صفحه فهرست ایمیل بازمی‌گرداند.

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

تغییر مقدار ناوبری.
PopUntilContentChange

این رفتار، محتوای نمایش داده شده را اولویت‌بندی می‌کند. اگر ابتدا مورد ۱ و سپس مورد ۲ را مشاهده کنید، با فشردن دکمه‌ی بازگشت، صرف نظر از طرح‌بندی، به مورد ۱ برمی‌گردید.

به مثال‌های زیر توجه کنید:

  • چندبخشی: شما مورد ۱ را در بخش جزئیات مشاهده می‌کنید، سپس روی مورد ۲ در لیست کلیک می‌کنید. بخش جزئیات به‌روزرسانی می‌شود. با فشردن دکمه‌ی بازگشت، بخش جزئیات به مورد ۱ بازگردانده می‌شود.
  • تک‌پنی: همان بازگشت محتوا رخ می‌دهد.

از این مورد زمانی استفاده کنید که کاربر انتظار دارد با استفاده از قابلیت بازگشت، به محتوای قبلی مشاهده شده بازگردد.

انتقال بین دو صفحه جزئیات
PopUntilCurrentDestinationChange

این رفتار، پشته پشتی را تا زمانی که مقصد ناوبری فعلی تغییر کند، بالا می‌آورد. این موضوع به طور یکسان برای طرح‌بندی‌های تک‌صفحه‌ای و چندصفحه‌ای اعمال می‌شود.

به مثال‌های زیر توجه کنید:

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

از این مورد زمانی استفاده کنید که نمایش بصری واضح از ناوبری فعلی برای تجربه کاربری بسیار مهم است.

پیمایش بین پنل‌های جزئیات و فهرست
PopLatest

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

بعد از اجرای این مراحل، کد شما باید مشابه کد زیر باشد:

val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
val scope = rememberCoroutineScope()

NavigableListDetailPaneScaffold(
    navigator = scaffoldNavigator,
    listPane = {
        AnimatedPane {
            MyList(
                onItemClick = { item ->
                    // Navigate to the detail pane with the passed item
                    scope.launch {
                        scaffoldNavigator.navigateTo(
                            ListDetailPaneScaffoldRole.Detail,
                            item
                        )
                    }
                },
            )
        }
    },
    detailPane = {
        AnimatedPane {
            // Show the detail pane content if selected item is available
            scaffoldNavigator.currentDestination?.contentKey?.let {
                MyDetails(it)
            }
        }
    },
)