یک طرح بندی صفحه پشتیبان بسازید

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

برای جزئیات بیشتر، دستورالعمل‌های صفحه پشتیبانی Material 3 را ببینید.

با NavigableSupportingPaneScaffold یک صفحه پشتیبانی را پیاده سازی کنید

NavigableSupportingPaneScaffold یک ابزار ترکیبی است که اجرای طرح بندی پنجره پشتیبانی را در Jetpack Compose ساده می کند. SupportingPaneScaffold را می‌پیچد و ناوبری داخلی و کنترل پیش‌بینی‌کننده پشت را اضافه می‌کند.

یک داربست پشتیبان تا سه جداره را پشتیبانی می کند:

  • صفحه اصلی : محتوای اصلی را نمایش می دهد.
  • پشتیبان : زمینه یا ابزارهای اضافی مربوط به صفحه اصلی را فراهم می کند.
  • صفحه اضافی (اختیاری) : برای محتوای تکمیلی در صورت نیاز استفاده می شود.

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

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

    محتوای اصلی که بیشتر صفحه نمایش را اشغال می کند و محتوای پشتیبانی در کنار آن است.
    شکل 1. طرح بندی صفحه پشتیبانی.

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

NavigableSupportingPaneScaffold بخشی از کتابخانه طرح‌بندی تطبیقی ​​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 نسخه 1.1.0-beta1 یا بالاتر باشد.

ژست برگشتی پیش‌بینی‌کننده را انتخاب کنید

برای فعال کردن انیمیشن‌های پیش‌بینی‌کننده پیش‌بینی در Android 15 یا پایین‌تر، باید برای پشتیبانی از حرکت پیش‌بینی‌کننده برگشت شرکت کنید. برای شرکت کردن، android:enableOnBackInvokedCallback="true" به <application> [برچسب> یا android:enableOnBackInvokedCallback="true" را به تگ <application> یا تگ‌های <activity> فردی در فایل AndroidManifest.xml خود اضافه کنید.

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

یک ناوبر ایجاد کنید

در پنجره‌های کوچک، هر بار فقط یک صفحه نمایش داده می‌شود، بنابراین از یک ThreePaneScaffoldNavigator برای جابه‌جایی به و از پنجره‌ها استفاده کنید. یک نمونه از ناوبر با rememberSupportingPaneScaffoldNavigator ایجاد کنید.

val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator()
val scope = rememberCoroutineScope()

ناوبر را به داربست رد کنید

داربست به یک ThreePaneScaffoldNavigator نیاز دارد که یک رابط نشان دهنده وضعیت داربست، ThreePaneScaffoldValue و یک PaneScaffoldDirective است.

NavigableSupportingPaneScaffold(
    navigator = scaffoldNavigator,
    mainPane = { /*...*/ },
    supportingPane = { /*...*/ },
)

قاب اصلی و پشتیبان مواردی هستند که حاوی محتوای شما هستند. از AnimatedPane برای اعمال انیمیشن های صفحه پیش فرض در حین پیمایش استفاده کنید. از مقدار داربست برای بررسی اینکه آیا صفحه پشتیبان پنهان است یا خیر استفاده کنید. اگر چنین است، دکمه ای را نمایش دهید که navigateTo(SupportingPaneScaffoldRole.Supporting) را فراخوانی می کند تا صفحه پشتیبانی نمایش داده شود.

در اینجا اجرای کامل داربست آمده است:

val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator()
val scope = rememberCoroutineScope()

NavigableSupportingPaneScaffold(
    navigator = scaffoldNavigator,
    mainPane = {
        AnimatedPane(
            modifier = Modifier
                .safeContentPadding()
                .background(Color.Red)
        ) {
            if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) {
                Button(
                    modifier = Modifier
                        .wrapContentSize(),
                    onClick = {
                        scope.launch {
                            scaffoldNavigator.navigateTo(SupportingPaneScaffoldRole.Supporting)
                        }
                    }
                ) {
                    Text("Show supporting pane")
                }
            } else {
                Text("Supporting pane is shown")
            }
        }
    },
    supportingPane = {
        AnimatedPane(modifier = Modifier.safeContentPadding()) {
            Text("Supporting pane")
        }
    }
)

استخراج مواد تشکیل دهنده پنجره

تک تک صفحات یک SupportingPaneScaffold را به اجزای سازنده خود استخراج کنید تا قابل استفاده مجدد و آزمایش شوند. اگر انیمیشن های پیش فرض را می خواهید از ThreePaneScaffoldScope برای دسترسی به AnimatedPane استفاده کنید:

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun ThreePaneScaffoldPaneScope.MainPane(
    shouldShowSupportingPaneButton: Boolean,
    onNavigateToSupportingPane: () -> Unit,
    modifier: Modifier = Modifier,
) {
    AnimatedPane(
        modifier = modifier.safeContentPadding()
    ) {
        // Main pane content
        if (shouldShowSupportingPaneButton) {
            Button(onClick = onNavigateToSupportingPane) {
                Text("Show supporting pane")
            }
        } else {
            Text("Supporting pane is shown")
        }
    }
}

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun ThreePaneScaffoldPaneScope.SupportingPane(
    modifier: Modifier = Modifier,
) {
    AnimatedPane(modifier = modifier.safeContentPadding()) {
        // Supporting pane content
        Text("This is the supporting pane")
    }
}

استخراج پنجره ها به اجزای ترکیبی استفاده از SupportingPaneScaffold را ساده می کند (موارد زیر را با اجرای کامل داربست در بخش قبل مقایسه کنید):

val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator()
val scope = rememberCoroutineScope()

NavigableSupportingPaneScaffold(
    navigator = scaffoldNavigator,
    mainPane = {
        MainPane(
            shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden,
            onNavigateToSupportingPane = {
                scope.launch {
                    scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary)
                }
            }
        )
    },
    supportingPane = { SupportingPane() },
)

اگر به کنترل بیشتری روی جنبه‌های خاصی از داربست نیاز دارید، به جای NavigableSupportingPaneScaffold از SupportingPaneScaffold استفاده کنید. این یک PaneScaffoldDirective و ThreePaneScaffoldValue یا ThreePaneScaffoldState به طور جداگانه می پذیرد. این انعطاف‌پذیری به شما امکان می‌دهد منطق سفارشی را برای فاصله بین پنجره‌ها پیاده‌سازی کنید و تعیین کنید که چند صفحه باید به طور همزمان نمایش داده شوند. همچنین می‌توانید با افزودن ThreePaneScaffoldPredictiveBackHandler پشتیبانی پیش‌بینی‌کننده را فعال کنید.

ThreePaneScaffoldPredictiveBackHandler را اضافه کنید

کنترل کننده پشتی پیش بینی کننده را که یک نمونه ناوبر داربست می گیرد وصل کنید و backBehavior مشخص کنید. این تعیین می‌کند که چگونه مقصدها در حین ناوبری برگشتی از پشته بیرون می‌آیند. سپس scaffoldDirective و scaffoldState را به SupportingPaneScaffold منتقل کنید. از اضافه باری استفاده کنید که یک ThreePaneScaffoldState می پذیرد و از scaffoldNavigator.scaffoldState عبور می کند.

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

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

val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator()
val scope = rememberCoroutineScope()

ThreePaneScaffoldPredictiveBackHandler(
    navigator = scaffoldNavigator,
    backBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange
)

SupportingPaneScaffold(
    directive = scaffoldNavigator.scaffoldDirective,
    scaffoldState = scaffoldNavigator.scaffoldState,
    mainPane = {
        MainPane(
            shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden,
            onNavigateToSupportingPane = {
                scope.launch {
                    scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary)
                }
            }
        )
    },
    supportingPane = { SupportingPane() },
)