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

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

ज़्यादा जानकारी के लिए, 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'
  • अडैप्टिव: लो-लेवल बिल्डिंग ब्लॉक, जैसे कि HingeInfo और Posture

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

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

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

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

Android 15 या इससे पहले के वर्शन में, पीछे जाने पर झलक दिखाने वाले ऐनिमेशन की सुविधा चालू करने के लिए, आपको पीछे जाने पर झलक दिखाने वाले हाथ के जेस्चर की सुविधा के लिए ऑप्ट-इन करना होगा. शामिल होने के लिए, अपनी AndroidManifest.xml फ़ाइल में <application> टैग या अलग-अलग <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")
            }

        }
    }
)

पैनल कंपोज़ेबल को अलग करना

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) },
)