साथ काम करने वाले पैनल का लेआउट बनाएं

सपोर्टिंग पैन लेआउट, ऐप्लिकेशन के मुख्य कॉन्टेंट पर उपयोगकर्ता का ध्यान बनाए रखता है. साथ ही, काम की जानकारी दिखाता है. उदाहरण के लिए, मुख्य पैन में किसी फ़िल्म के बारे में जानकारी दिख सकती है. वहीं, साथ वाले पैन में मिलती-जुलती फ़िल्में, एक ही निर्देशक की फ़िल्में या एक ही कलाकारों की फ़िल्में दिख सकती हैं.

ज़्यादा जानकारी के लिए, Material 3 के साथ काम करने वाले पैन के दिशा-निर्देश देखें.

स्काफ़ोल्ड के साथ एक सपोर्टिंग पैन लागू करना

NavigableSupportingPaneScaffold एक कंपोज़ेबल है. यह Jetpack Compose में, सपोर्टिंग पैन लेआउट को लागू करने की प्रोसेस को आसान बनाता है. यह SupportingPaneScaffold को रैप करता है. साथ ही, इसमें नेविगेशन और अनुमानित बैक हैंडलिंग की सुविधा पहले से मौजूद होती है.

सहायक पैनल के लिए उपलब्ध लेआउट में ज़्यादा से ज़्यादा तीन पैनल हो सकते हैं:

  • मुख्य पैनल: इसमें मुख्य कॉन्टेंट दिखता है.
  • सपोर्टिंग पैन: यह मुख्य पैन से जुड़ी ज़्यादा जानकारी या टूल उपलब्ध कराता है.
  • अतिरिक्त पैन (ज़रूरी नहीं): इसका इस्तेमाल, ज़रूरत पड़ने पर पूरक कॉन्टेंट के लिए किया जाता है.

विंडो के साइज़ के हिसाब से, स्कैफ़ोल्ड अपने-आप अडजस्ट हो जाता है:

  • बड़ी विंडो में, मुख्य और सहायक पैन एक साथ दिखते हैं.
  • छोटी विंडो में, एक बार में सिर्फ़ एक पैन दिखता है. जब उपयोगकर्ता नेविगेट करते हैं, तब पैन बदलता है.

    मुख्य कॉन्टेंट, डिसप्ले के ज़्यादातर हिस्से पर दिखता है. साथ ही, उससे जुड़ा कॉन्टेंट भी दिखता है.
    पहली इमेज. पेन लेआउट की सुविधा काम करती है.

डिपेंडेंसी जोड़ें

NavigableSupportingPaneScaffold, Material 3 अडैप्टिव लेआउट लाइब्रेरी का हिस्सा है.

अपने ऐप्लिकेशन या मॉड्यूल की build.gradle फ़ाइल में, मिलती-जुलती ये तीन डिपेंडेंसी जोड़ें:

Kotlin

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

Groovy

implementation 'androidx.compose.material3.adaptive:adaptive'
implementation 'androidx.compose.material3.adaptive:adaptive-layout'
implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
  • adaptive: लो-लेवल बिल्डिंग ब्लॉक, जैसे कि HingeInfo और Posture

  • adaptive-layout: अडैप्टिव लेआउट, जैसे कि ListDetailPaneScaffold और SupportingPaneScaffold

  • adaptive-navigation: इसमें पैन के अंदर और उनके बीच नेविगेट करने के लिए कंपोज़ेबल शामिल होते हैं. साथ ही, इसमें ऐसे अडैप्टिव लेआउट भी शामिल होते हैं जो डिफ़ॉल्ट रूप से नेविगेशन की सुविधा देते हैं. जैसे, NavigableListDetailPaneScaffold और NavigableSupportingPaneScaffold

पक्का करें कि आपके प्रोजेक्ट में compose-material3-adaptive वर्शन 1.1.0-beta1 या इसके बाद का वर्शन शामिल हो.

पीछे जाने पर झलक दिखाने वाले हाथ के जेस्चर की सुविधा के लिए ऑप्ट-इन करना

Android 15 या इससे पहले के वर्शन में, प्रिडिक्टिव बैक ऐनिमेशन चालू करने के लिए, आपको प्रिडिक्टिव बैक जेस्चर की सुविधा के लिए ऑप्ट-इन करना होगा. ऑप्ट-इन करने के लिए, <application> टैग या अपनी AndroidManifest.xml फ़ाइल में मौजूद अलग-अलग <activity> टैग में android:enableOnBackInvokedCallback="true" जोड़ें.

जब आपका ऐप्लिकेशन, Android 16 (एपीआई लेवल 36) या इसके बाद के वर्शन को टारगेट करता है, तो अनुमानित बैक सुविधा डिफ़ॉल्ट रूप से चालू हो जाती है.

नेविगेटर बनाना

छोटी विंडो में, एक बार में सिर्फ़ एक पैनल दिखता है. इसलिए, पैनलों के बीच आगे-पीछे जाने के लिए, ThreePaneScaffoldNavigator का इस्तेमाल करें. rememberSupportingPaneScaffoldNavigator की मदद से, नेविगेटर का एक इंस्टेंस बनाएं.

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

नेविगेटर को स्कैफ़ोल्ड में पास करें

स्कैफ़ोल्ड के लिए ThreePaneScaffoldNavigator की ज़रूरत होती है. यह स्कैफ़ोल्ड की स्थिति, ThreePaneScaffoldValue, और PaneScaffoldDirective को दिखाने वाला इंटरफ़ेस होता है.

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

मुख्य पैन और साथ में दिखने वाला पैन, कंपोज़ेबल होते हैं. इनमें आपका कॉन्टेंट होता है. नेविगेशन के दौरान डिफ़ॉल्ट पैन ऐनिमेशन लागू करने के लिए, AnimatedPane का इस्तेमाल करें. स्केफ़ोल्ड वैल्यू का इस्तेमाल करके यह पता लगाएं कि सहायता वाला पैनल छिपा हुआ है या नहीं. अगर ऐसा है, तो एक बटन दिखाएं. यह बटन, सहायता वाले पैनल को दिखाने के लिए navigateTo(SupportingPaneScaffoldRole.Supporting) को कॉल करता है.

बड़ी स्क्रीन के लिए, ThreePaneScaffoldNavigator.navigateBack() तरीके का इस्तेमाल करके, साथ में दिखने वाले पैनल को खारिज करें. इसके लिए, BackNavigationBehavior.PopUntilScaffoldValueChange कॉन्स्टेंट पास करें. इस तरीके को कॉल करने से, NavigableSupportingPaneScaffold का रीकंपोज़िशन होता है. रीकंपोज़िशन के दौरान, ThreePaneScaffoldNavigator.currentDestination प्रॉपर्टी की जांच करें. इससे यह तय किया जा सकेगा कि सहायता वाला पैन दिखाया जाए या नहीं.

यहां स्कैफ़ोल्ड को पूरी तरह से लागू करने का तरीका बताया गया है:

val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator()
val scope = rememberCoroutineScope()
val backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange

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()) {
            Column {
                // Allow users to dismiss the supporting pane. Use back navigation to
                // hide an expanded supporting pane.
                if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Expanded) {
                    // Material design principles promote the usage of a right-aligned
                    // close (X) button.
                    IconButton(
                        modifier =  Modifier.align(Alignment.End).padding(16.dp),
                        onClick = {
                            scope.launch {
                                scaffoldNavigator.navigateBack(backNavigationBehavior)
                            }
                        }
                    ) {
                        Icon(Icons.Default.Close, contentDescription = "Close")
                    }
                }
                Text("Supporting pane")
            }

        }
    }
)

Extract pane composables

SupportingPaneScaffold के अलग-अलग पैन को उनके अपने कंपोज़ेबल में एक्सट्रैक्ट करें, ताकि उन्हें फिर से इस्तेमाल किया जा सके और उनकी जांच की जा सके. अगर आपको डिफ़ॉल्ट ऐनिमेशन चाहिए, तो AnimatedPane को ऐक्सेस करने के लिए ThreePaneScaffoldScope का इस्तेमाल करें:

@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(
    scaffoldNavigator: ThreePaneScaffoldNavigator<Any>,
    modifier: Modifier = Modifier,
    backNavigationBehavior: BackNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange,
) {
    val scope = rememberCoroutineScope()
    AnimatedPane(modifier = Modifier.safeContentPadding()) {
        Column {
            // Allow users to dismiss the supporting pane. Use back navigation to
            // hide an expanded supporting pane.
            if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Expanded) {
                // Material design principles promote the usage of a right-aligned
                // close (X) button.
                IconButton(
                    modifier =  modifier.align(Alignment.End).padding(16.dp),
                    onClick = {
                        scope.launch {
                            scaffoldNavigator.navigateBack(backNavigationBehavior)
                        }
                    }
                ) {
                    Icon(Icons.Default.Close, contentDescription = "Close")
                }
            }
            Text("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(scaffoldNavigator = scaffoldNavigator) },
)

अगर आपको स्कैफ़ोल्ड के कुछ पहलुओं पर ज़्यादा कंट्रोल चाहिए, तो 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(scaffoldNavigator = scaffoldNavigator) },
)