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

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

ज़्यादा जानकारी के लिए, 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")

शानदार

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

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

  • अडैप्टिव-नेविगेशन: पैनल के बीच और उनमें नेविगेट करने के लिए कंपोज़ेबल. साथ ही, ऐसे अडैप्टिव लेआउट जिनमें डिफ़ॉल्ट रूप से नेविगेशन की सुविधा होती है. जैसे, 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 के अलग-अलग पैनल को, उनके कंपोज़ेबल में निकालें, ताकि उन्हें फिर से इस्तेमाल किया जा सके और उनकी जांच की जा सके. अगर आपको डिफ़ॉल्ट ऐनिमेशन चाहिए, तो 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(
    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) },
)

अगर आपको स्केफ़ोल्ड के कुछ पहलुओं पर ज़्यादा कंट्रोल चाहिए, तो SupportingPaneScaffold के बजाय NavigableSupportingPaneScaffold का इस्तेमाल करें. यह एक 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) },
)