अलग-अलग स्क्रीन साइज़ के साथ काम करने की सुविधा से, आपके ऐप्लिकेशन को अलग-अलग तरह के डिवाइसों और ज़्यादा से ज़्यादा उपयोगकर्ताओं के लिए ऐक्सेस किया जा सकता है.
ज़्यादा से ज़्यादा स्क्रीन साइज़ के साथ काम करने के लिए, अपने ऐप्लिकेशन के लेआउट को रिस्पॉन्सिव और अडैप्टिव बनाएं. रिस्पॉन्सिव/अडैप्टिव लेआउट, स्क्रीन के साइज़ के बावजूद उपयोगकर्ता को बेहतर अनुभव देते हैं. इनकी मदद से, आपके ऐप्लिकेशन को फ़ोन, टैबलेट, फ़ोल्ड किए जा सकने वाले डिवाइस, ChromeOS डिवाइसों, पोर्ट्रेट और लैंडस्केप ओरिएंटेशन, और मल्टी-विंडो मोड जैसे कॉन्फ़िगरेशन में दिखाया जा सकता है.
रिस्पॉन्सिव/अडैप्टिव लेआउट, डिसप्ले के लिए उपलब्ध स्पेस के हिसाब से बदलते हैं. बदलावों में, लेआउट में छोटे बदलाव करना शामिल है, ताकि डिवाइस के स्क्रीन साइज़ के हिसाब से ऐप्लिकेशन के कॉन्टेंट को सही तरीके से दिखाया जा सके (रिस्पॉन्सिव डिज़ाइन). इसके अलावा, एक लेआउट को पूरी तरह से दूसरे लेआउट से बदलना भी बदलावों में शामिल है, ताकि आपका ऐप्लिकेशन अलग-अलग डिसप्ले साइज़ के हिसाब से कॉन्टेंट को सही तरीके से दिखा सके (अडैप्टिव डिज़ाइन).
डिक्लेरेटिव यूज़र इंटरफ़ेस टूलकिट के तौर पर, Jetpack Compose ऐसे लेआउट डिज़ाइन करने और लागू करने के लिए बेहतरीन है जो अलग-अलग डिसप्ले साइज़ पर कॉन्टेंट को अलग-अलग तरीके से रेंडर करने के लिए, डाइनैमिक तौर पर बदलते हैं.
स्क्रीन-लेवल के कॉम्पोज़ेबल के लिए, लेआउट में बड़े बदलावों को साफ़ तौर पर दिखाना
पूरे ऐप्लिकेशन का लेआउट बनाने के लिए Compose का इस्तेमाल करने पर, ऐप्लिकेशन-लेवल और स्क्रीन-लेवल के कॉम्पोज़ेबल, आपके ऐप्लिकेशन के रेंडर करने के लिए दिए गए पूरे स्पेस पर कब्जा कर लेते हैं. डिज़ाइन के इस लेवल पर, बड़ी स्क्रीन का फ़ायदा पाने के लिए, स्क्रीन के पूरे लेआउट में बदलाव करना सही रहेगा.
लेआउट से जुड़े फ़ैसले लेने के लिए, फ़िज़िकल और हार्डवेयर वैल्यू का इस्तेमाल करने से बचें. किसी तय वैल्यू के आधार पर फ़ैसले लेने का प्रलोभन हो सकता है (क्या डिवाइस टैबलेट है? क्या फ़िज़िकल स्क्रीन का आसपेक्ट रेशियो तय है?), लेकिन इन सवालों के जवाब, यह तय करने के लिए काम के नहीं हो सकते कि आपका यूज़र इंटरफ़ेस किस तरह के स्क्रीन साइज़ पर काम कर सकता है.
टैबलेट पर, कोई ऐप्लिकेशन कई विंडो मोड में चल सकता है. इसका मतलब है कि ऐप्लिकेशन, स्क्रीन को किसी दूसरे ऐप्लिकेशन के साथ बांट सकता है. ChromeOS पर, कोई ऐप्लिकेशन ऐसी विंडो में हो सकता है जिसका साइज़ बदला जा सकता है. हो सकता है कि एक से ज़्यादा फ़िज़िकल स्क्रीन हों, जैसे कि फ़ोल्ड किए जा सकने वाले डिवाइस में. इन सभी मामलों में, कॉन्टेंट दिखाने के तरीके का फ़ैसला लेने के लिए, स्क्रीन का साइज़ मायने नहीं रखता.
इसके बजाय, आपको स्क्रीन के उस हिस्से के आधार पर फ़ैसले लेने चाहिए जो आपके ऐप्लिकेशन के लिए तय किया गया है. जैसे, Jetpack WindowManager लाइब्रेरी से मिली विंडो की मौजूदा मेट्रिक. Compose ऐप्लिकेशन में WindowManager का इस्तेमाल करने का तरीका जानने के लिए, JetNews सैंपल देखें.
इस तरीके का इस्तेमाल करने से, आपका ऐप्लिकेशन ज़्यादा बेहतर तरीके से काम करता है. ऐसा इसलिए, क्योंकि यह ऊपर बताई गई सभी स्थितियों में सही तरीके से काम करेगा. अपने लेआउट को स्क्रीन के उपलब्ध स्पेस के हिसाब से बनाने से, ChromeOS जैसे प्लैटफ़ॉर्म और टैबलेट और फ़ोल्डेबल जैसे फ़ॉर्म फ़ैक्टर के साथ काम करने के लिए, खास तरीके से हैंडल करने की ज़रूरत कम हो जाती है.
अपने ऐप्लिकेशन के लिए उपलब्ध जगह का पता लगाने के बाद, रॉ साइज़ को काम के साइज़ क्लास में बदलना मददगार होता है. इस बारे में विंडो साइज़ के क्लास का इस्तेमाल करना में बताया गया है. यह साइज़ को स्टैंडर्ड साइज़ की बकेट में ग्रुप करता है. ये ब्रेकपॉइंट होते हैं, जिन्हें सबसे यूनीक मामलों के लिए आपके ऐप्लिकेशन को ऑप्टिमाइज़ करने के लिए, आसानी के साथ फ़्लेक्सिबिलिटी को संतुलित करने के लिए डिज़ाइन किया गया है. साइज़ क्लास, आपके ऐप्लिकेशन की पूरी विंडो के बारे में बताती हैं. इसलिए, लेआउट से जुड़े उन फ़ैसलों के लिए इन क्लास का इस्तेमाल करें जिनका असर आपकी पूरी स्क्रीन के लेआउट पर पड़ता है. इन साइज़ क्लास को स्टेटस के तौर पर पास किया जा सकता है. इसके अलावा, नेस्ट किए गए कॉम्पोज़ेबल में पास करने के लिए, डेरिव्ड स्टेटस बनाने के लिए अतिरिक्त लॉजिक भी इस्तेमाल किया जा सकता है.
@Composable fun MyApp( windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass ) { // Perform logic on the size class to decide whether to show the top app bar. val showTopAppBar = windowSizeClass.windowHeightSizeClass != WindowHeightSizeClass.COMPACT // MyScreen knows nothing about window sizes, and performs logic based on a Boolean flag. MyScreen( showTopAppBar = showTopAppBar, /* ... */ ) }
लेयर वाले इस तरीके से, स्क्रीन साइज़ के लॉजिक को एक ही जगह पर सीमित किया जाता है. इसके बजाय, इसे आपके ऐप्लिकेशन में कई जगहों पर फैलाया जाता है, जिन्हें सिंक रखना ज़रूरी होता है. यह एक ही जगह, स्टेटस जनरेट करती है. इसे अन्य कॉम्पोज़ेबल में साफ़ तौर पर पास किया जा सकता है, ठीक उसी तरह जैसे किसी भी अन्य ऐप्लिकेशन स्टेटस के लिए किया जाता है. साफ़ तौर पर राज्य को पास करने से, अलग-अलग कॉम्पोज़ेबल आसान हो जाते हैं, क्योंकि वे सिर्फ़ सामान्य कॉम्पोज़ेबल फ़ंक्शन होंगे जो अन्य डेटा के साथ साइज़ क्लास या तय किए गए कॉन्फ़िगरेशन को लेते हैं.
नेस्ट किए गए फ़्लेक्सिबल कॉम्पोज़ेबल को फिर से इस्तेमाल किया जा सकता है
कॉम्पोज़ेबल को कई जगहों पर इस्तेमाल किया जा सकता है. अगर किसी कॉम्पोज़ेबल के लिए यह तय किया जाता है कि उसे हमेशा किसी खास साइज़ में किसी खास जगह पर रखा जाएगा, तो उसे किसी दूसरी जगह या अलग साइज़ में फिर से इस्तेमाल करना मुश्किल होगा. इसका यह भी मतलब है कि अलग-अलग और फिर से इस्तेमाल किए जा सकने वाले कॉम्पोज़ेबल, "ग्लोबल" साइज़ की जानकारी पर निर्भर नहीं होने चाहिए.
इस उदाहरण पर विचार करें: नेस्ट किए गए ऐसे कॉम्पोज़ेबल की कल्पना करें जो सूची की जानकारी वाला लेआउट लागू करता है. यह एक पैनल या दो पैनल को एक साथ दिखा सकता है.
हम चाहते हैं कि यह फ़ैसला, ऐप्लिकेशन के पूरे लेआउट का हिस्सा हो. इसलिए, हम ऊपर बताए गए तरीके से, स्क्रीन-लेवल के कॉम्पोज़ेबल से फ़ैसला पास करते हैं:
@Composable fun AdaptivePane( showOnePane: Boolean, /* ... */ ) { if (showOnePane) { OnePane(/* ... */) } else { TwoPane(/* ... */) } }
अगर हमें उपलब्ध जगह के हिसाब से, कॉम्पोज़ेबल का लेआउट अपने-आप बदलने की सुविधा चाहिए, तो क्या करना होगा? उदाहरण के लिए, ऐसा कार्ड जिसमें जगह होने पर ज़्यादा जानकारी दिखे. हमें उपलब्ध साइज़ के आधार पर कुछ लॉजिक लागू करना है, लेकिन कौनसा साइज़?
जैसा कि हमने ऊपर देखा, हमें डिवाइस की असल स्क्रीन के साइज़ का इस्तेमाल करने से बचना चाहिए. यह कई स्क्रीन के लिए सटीक नहीं होगा. साथ ही, अगर ऐप्लिकेशन फ़ुलस्क्रीन में नहीं है, तो भी यह सटीक नहीं होगा.
कॉम्पोज़ेबल, स्क्रीन-लेवल का कॉम्पोज़ेबल नहीं होता. इसलिए, फिर से इस्तेमाल करने की सुविधा को बढ़ाने के लिए, हमें मौजूदा विंडो मेट्रिक का सीधे तौर पर इस्तेमाल नहीं करना चाहिए. अगर कॉम्पोनेंट को पैडिंग के साथ रखा जा रहा है (जैसे, इनसेट के लिए) या नेविगेशन रेल या ऐप्लिकेशन बार जैसे कॉम्पोनेंट मौजूद हैं, तो कॉम्पोज़ेबल के लिए उपलब्ध जगह, ऐप्लिकेशन के लिए उपलब्ध कुल जगह से काफ़ी अलग हो सकती है.
इसलिए, हमें उस चौड़ाई का इस्तेमाल करना चाहिए जो कॉम्पोज़ेबल को खुद को रेंडर करने के लिए दी गई है. इस चौड़ाई को पाने के लिए हमारे पास दो विकल्प हैं:
अगर आपको कॉन्टेंट के दिखने की जगह या तरीका बदलना है, तो लेआउट को रिस्पॉन्सिव बनाने के लिए, बदलाव करने वाले टूल के कलेक्शन या कस्टम लेआउट का इस्तेमाल किया जा सकता है. यह बहुत आसान हो सकता है कि किसी बच्चे को उपलब्ध सभी जगह भरने के लिए कहा जाए या फिर अगर ज़रूरत हो, तो बच्चों को एक से ज़्यादा कॉलम में व्यवस्थित किया जाए.
अगर आपको क्या दिखाना है, तो BoxWithConstraints
का इस्तेमाल बेहतर विकल्प के तौर पर किया जा सकता है. यह कॉम्पोनेंट, मेज़रमेंट से जुड़ी पाबंदियां उपलब्ध कराता है. इनका इस्तेमाल, उपलब्ध जगह के आधार पर अलग-अलग कॉम्पोनेंट को कॉल करने के लिए किया जा सकता है. हालांकि, इसकी कुछ कीमत चुकाई जानी पड़ती है, क्योंकि BoxWithConstraints
, लेआउट के चरण तक कॉम्पोज़िशन को तब तक के लिए रोक देता है, जब तक इन सीमाओं के बारे में पता नहीं चल जाता. इस वजह से, लेआउट के दौरान ज़्यादा काम करना पड़ता है.
@Composable fun Card(/* ... */) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(/* ... */) Title(/* ... */) } } else { Row { Column { Title(/* ... */) Description(/* ... */) } Image(/* ... */) } } } }
पक्का करें कि अलग-अलग साइज़ के लिए सारा डेटा उपलब्ध हो
स्क्रीन के अतिरिक्त स्पेस का फ़ायदा लेते समय, बड़ी स्क्रीन पर उपयोगकर्ता को छोटी स्क्रीन के मुकाबले ज़्यादा कॉन्टेंट दिखाया जा सकता है. इस व्यवहार के साथ किसी कॉम्पोज़ेबल को लागू करते समय, डेटा को मौजूदा साइज़ के साइड इफ़ेक्ट के तौर पर लोड करने के बजाय, डेटा को लोड करने का बेहतर तरीका अपनाया जा सकता है.
हालांकि, यह एकतरफ़ा डेटा फ़्लो के सिद्धांतों के ख़िलाफ़ है. इसमें, डेटा को होस्ट किया जा सकता है और सही तरीके से रेंडर करने के लिए, कॉम्पोज़ेबल को दिया जा सकता है. कॉम्पोज़ेबल में ज़रूरत के मुताबिक डेटा होना चाहिए, ताकि कॉम्पोज़ेबल में हमेशा वह डेटा मौजूद रहे जिसे किसी भी साइज़ में दिखाना ज़रूरी हो. भले ही, डेटा के कुछ हिस्से का इस्तेमाल हमेशा न किया जाए.
@Composable fun Card( imageUrl: String, title: String, description: String ) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(imageUrl) Title(title) } } else { Row { Column { Title(title) Description(description) } Image(imageUrl) } } } }
Card
के उदाहरण पर आधारित, ध्यान दें कि हम हमेशा description
को Card
पर पास करते हैं. description
का इस्तेमाल सिर्फ़ तब किया जाता है, जब चौड़ाई की वजह से उसे दिखाया जा सकता हो. हालांकि, Card
के लिए हमेशा description
की ज़रूरत होती है, फिर चाहे उपलब्ध चौड़ाई कितनी भी हो.
हमेशा डेटा पास करने से, अडैप्टिव लेआउट को आसान बनाया जा सकता है. ऐसा करने से, लेआउट में बदलाव होने पर, उन पर असर कम पड़ता है. जैसे, विंडो का साइज़ बदलने, ओरिएंटेशन में बदलाव करने या डिवाइस को फ़ोल्ड करने और अनफ़ोल्ड करने पर.
इस सिद्धांत की मदद से, लेआउट में होने वाले बदलावों के दौरान भी स्टेटस को बनाए रखा जा सकता है. होस्ट करने की सुविधा का इस्तेमाल करके, ऐसी जानकारी को सेव किया जा सकता है जिसका इस्तेमाल सभी साइज़ में नहीं किया जा सकता. इससे, लेआउट के साइज़ में बदलाव होने पर, उपयोगकर्ता की स्थिति को बनाए रखा जा सकता है. उदाहरण के लिए, हम showMore
बूलियन फ़्लैग को होस्ट कर सकते हैं, ताकि जब लेआउट का साइज़ बदलने पर, ब्यौरा छिपाने और दिखाने के बीच स्विच किया जाए, तो उपयोगकर्ता की स्थिति बनी रहे:
@Composable fun Card( imageUrl: String, title: String, description: String ) { var showMore by remember { mutableStateOf(false) } BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(imageUrl) Title(title) } } else { Row { Column { Title(title) Description( description = description, showMore = showMore, onShowMoreToggled = { newValue -> showMore = newValue } ) } Image(imageUrl) } } } }
ज़्यादा जानें
Compose में कस्टम लेआउट के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें.
सैंपल ऐप्लिकेशन
- CanonicalLayouts, ऐसे डिज़ाइन पैटर्न का कलेक्शन है जो बड़ी स्क्रीन वाले डिवाइसों पर बेहतर उपयोगकर्ता अनुभव देते हैं
- JetNews में, ऐसे ऐप्लिकेशन को डिज़ाइन करने का तरीका बताया गया है जो उपलब्ध जगह का इस्तेमाल करने के लिए, अपने यूज़र इंटरफ़ेस (यूआई) में बदलाव करता है
- Reply एक अडैप्टिव सैंपल है, जो मोबाइल, टैबलेट, और फ़ोल्ड किए जा सकने वाले डिवाइसों पर काम करता है
- Now in Android एक ऐसा ऐप्लिकेशन है जो अलग-अलग स्क्रीन साइज़ के हिसाब से अडैप्टिव लेआउट का इस्तेमाल करता है
वीडियो
- किसी भी स्क्रीन साइज़ के लिए Android यूज़र इंटरफ़ेस (यूआई) बनाना
- डिवाइस के फ़ॉर्म फ़ैक्टर | Android डेवलपर समिट '22
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
- कॉम्पोनेंट को मौजूदा कोड से मैप करना
- लेआउट बनाने के बारे में बुनियादी बातें
- Jetpack Compose के चरण