इस पेज पर, Android 12 (एपीआई लेवल 31) में, विजेट के साइज़ और ज़्यादा फ़्लेक्सिबिलिटी के लिए किए गए सुधारों के बारे में बताया गया है. इसमें यह भी बताया गया है कि अपने विजेट का साइज़ कैसे तय करें.
विजेट के साइज़ और लेआउट के लिए, बेहतर एपीआई का इस्तेमाल करना
Android 12 (एपीआई लेवल 31) से, साइज़ एट्रिब्यूट की बेहतर जानकारी दी जा सकती है. साथ ही, यहां दिए गए तरीके अपनाकर फ़्लेक्सिबल लेआउट बनाए जा सकते हैं. इनके बारे में यहां दिए गए सेक्शन में बताया गया है:
रिस्पॉन्सिव लेआउट या सटीक लेआउट उपलब्ध कराना.
Android के पिछले वर्शन में, OPTION_APPWIDGET_MIN_WIDTH, OPTION_APPWIDGET_MIN_HEIGHT, OPTION_APPWIDGET_MAX_WIDTH, और OPTION_APPWIDGET_MAX_HEIGHT एक्स्ट्रा का इस्तेमाल करके, किसी विजेट के साइज़ की रेंज पता की जा सकती है. इसके बाद, विजेट के साइज़ का अनुमान लगाया जा सकता है. हालांकि, यह तरीका हर स्थिति में काम नहीं करता. Android 12 या इसके बाद के वर्शन को टारगेट करने वाले विजेट के लिए, हमारा सुझाव है कि रिस्पॉन्सिव या सटीक लेआउट उपलब्ध कराएं.
विजेट के साइज़ से जुड़ी अन्य पाबंदियों के बारे में बताएं
Android 12 में ऐसे एपीआई जोड़े गए हैं जिनकी मदद से, यह पक्का किया जा सकता है कि आपका विजेट अलग-अलग स्क्रीन साइज़ वाले डिवाइसों पर ज़्यादा भरोसेमंद तरीके से काम करे.
मौजूदा minWidth, minHeight, minResizeWidth, और minResizeHeight एट्रिब्यूट के साथ-साथ, इन नए appwidget-provider एट्रिब्यूट का इस्तेमाल करें:
targetCellWidthऔरtargetCellHeight: इनसे, लॉन्चर ग्रिड सेल के हिसाब से विजेट का टारगेट साइज़ तय किया जाता है. अगर इन्हें तय किया जाता है, तोminWidthयाminHeightके बजाय इन एट्रिब्यूट का इस्तेमाल किया जाता है.maxResizeWidthऔरmaxResizeHeight: इनसे, लॉन्चर के उस ज़्यादा से ज़्यादा साइज़ के बारे में पता चलता है जिस पर उपयोगकर्ता विजेट का साइज़ बदल सकता है.
यहां दिए गए एक्सएमएल में, साइज़िंग एट्रिब्यूट इस्तेमाल करने का तरीका बताया गया है.
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:targetCellWidth="3" android:targetCellHeight="2" android:maxResizeWidth="250dp" android:maxResizeHeight="110dp"> </appwidget-provider>
रिस्पॉन्सिव लेआउट उपलब्ध कराना
अगर विजेट के साइज़ के हिसाब से लेआउट में बदलाव करना है, तो हमारा सुझाव है कि लेआउट का एक छोटा सेट बनाएं. हर लेआउट, साइज़ की एक रेंज के लिए मान्य होता है. अगर ऐसा नहीं किया जा सकता, तो इस पेज पर बताए गए तरीके के मुताबिक, रनटाइम में विजेट के सटीक साइज़ के आधार पर लेआउट उपलब्ध कराएं.
इस सुविधा की मदद से, ऐप्लिकेशन को आसानी से स्केल किया जा सकता है. साथ ही, सिस्टम बेहतर तरीके से काम करता है. ऐसा इसलिए, क्योंकि जब सिस्टम अलग-अलग साइज़ में विजेट दिखाता है, तो उसे हर बार ऐप्लिकेशन को चालू नहीं करना पड़ता.
यहां दिए गए कोड के उदाहरण में, लेआउट की सूची देने का तरीका बताया गया है.
override fun onUpdate( /* ... */ ) { val smallView = RemoteViews( /* ... */ ) val tallView = RemoteViews( /* ... */ ) val wideView = RemoteViews( /* ... */ ) val viewMapping: Map<SizeF, RemoteViews> = mapOf( SizeF(150f, 100f) to smallView, SizeF(150f, 200f) to tallView, SizeF(215f, 100f) to wideView ) val remoteViews = RemoteViews(viewMapping) appWidgetManager.updateAppWidget(id, remoteViews) }
मान लें कि विजेट में ये एट्रिब्यूट हैं:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minResizeWidth="160dp" android:minResizeHeight="110dp" android:maxResizeWidth="250dp" android:maxResizeHeight="200dp"> </appwidget-provider>
ऊपर दिए गए कोड स्निपेट का मतलब यह है:
smallView160 डीपी (minResizeWidth) × 110 डीपी (minResizeHeight) से लेकर 160 डीपी × 199 डीपी (अगला कटऑफ़ पॉइंट - 1 डीपी) तक के साइज़ के साथ काम करता है.tallView160dp × 200dp से लेकर 214dp (अगला कटऑफ़ पॉइंट - 1) × 200dp तक के साइज़ के साथ काम करता है.wideView215 डीपी × 110 डीपी (minResizeHeight) से लेकर 250 डीपी (maxResizeWidth) × 200 डीपी (maxResizeHeight) तक के डाइमेंशन वाले इमेज फ़ॉर्मैट काम करते हैं.
आपके विजेट का साइज़, minResizeWidth × minResizeHeight से maxResizeWidth × maxResizeHeight के बीच होना चाहिए. इस रेंज में, लेआउट बदलने के लिए कटऑफ़ पॉइंट तय किया जा सकता है.
सटीक लेआउट उपलब्ध कराना
अगर रिस्पॉन्सिव लेआउट का छोटा सेट उपलब्ध कराना मुमकिन नहीं है, तो इसके बजाय ऐसे अलग-अलग लेआउट उपलब्ध कराएं जो विजेट के साइज़ के हिसाब से बने हों. आम तौर पर, फ़ोन के लिए दो साइज़ (पोर्ट्रेट और लैंडस्केप मोड) और फ़ोल्ड किए जा सकने वाले डिवाइसों के लिए चार साइज़ होते हैं.
इस समाधान को लागू करने के लिए, आपके ऐप्लिकेशन को यह तरीका अपनाना होगा:
ओवरलोड
AppWidgetProvider.onAppWidgetOptionsChanged(), जिसे साइज़ का सेट बदलने पर कॉल किया जाता है.AppWidgetManager.getAppWidgetOptions()को कॉल करें. इससे साइज़ वालीBundleमिलती है.BundleसेAppWidgetManager.OPTION_APPWIDGET_SIZESकुंजी को ऐक्सेस करें.
नीचे दिए गए कोड के उदाहरण में, सटीक लेआउट देने का तरीका बताया गया है.
override fun onAppWidgetOptionsChanged( context: Context, appWidgetManager: AppWidgetManager, id: Int, newOptions: Bundle? ) { super.onAppWidgetOptionsChanged(context, appWidgetManager, id, newOptions) // Get the new sizes. val sizes = newOptions?.let { BundleCompat.getParcelableArrayList( it, AppWidgetManager.OPTION_APPWIDGET_SIZES, SizeF::class.java ) } // Check that the list of sizes is provided by the launcher. if (sizes.isNullOrEmpty()) { return } // Map the sizes to the RemoteViews that you want. val remoteViews = RemoteViews(sizes.associateWith(::createRemoteViews)) appWidgetManager.updateAppWidget(id, remoteViews) } // Create the RemoteViews for the given size. private fun createRemoteViews(size: SizeF): RemoteViews { }
अपने विजेट का साइज़ तय करना
Android 12 या इसके बाद के वर्शन पर काम करने वाले डिवाइसों के लिए, हर विजेट को targetCellWidth और targetCellHeight तय करना होगा. इसके अलावा, Android के सभी वर्शन के लिए minWidth और minHeight तय करना होगा. इससे यह पता चलेगा कि डिफ़ॉल्ट रूप से, विजेट कम से कम कितनी जगह लेता है. हालांकि, जब उपयोगकर्ता अपनी होम स्क्रीन पर कोई विजेट जोड़ते हैं, तो आम तौर पर यह आपके तय किए गए कम से कम चौड़ाई और लंबाई से ज़्यादा जगह लेता है.
Android की होम स्क्रीन पर, उपयोगकर्ताओं को उपलब्ध स्पेस की ग्रिड दिखती है. इस पर वे विजेट और आइकॉन रख सकते हैं. यह ग्रिड, डिवाइस के हिसाब से अलग-अलग हो सकता है. उदाहरण के लिए, कई हैंडसेट में 5x4 ग्रिड होता है. वहीं, टैबलेट में बड़ा ग्रिड हो सकता है. जब आपका विजेट जोड़ा जाता है, तो उसे कम से कम उतनी जगह में फैलाया जाता है जितनी में वह हॉरिज़ॉन्टल और वर्टिकल तौर पर फ़िट हो सके. ऐसा इसलिए किया जाता है, ताकि Android 12 या इसके बाद के वर्शन पर काम करने वाले डिवाइसों पर, targetCellWidth और targetCellHeight की ज़रूरी शर्तें पूरी की जा सकें. इसके अलावा, Android 11 (एपीआई लेवल 30) या इससे पहले के वर्शन पर काम करने वाले डिवाइसों पर, minWidth और minHeight की ज़रूरी शर्तें पूरी की जा सकें.
सेल के डाइमेंशन और अपने-आप सेट होने वाले मार्जिन, हर डिवाइस पर अलग-अलग होते हैं. यहां दी गई टेबल का इस्तेमाल करके, अपने विजेट के कम से कम डाइमेंशन का अनुमान लगाएं. यह अनुमान, 5x4 ग्रिड वाले सामान्य हैंडसेट के हिसाब से लगाया गया है. इसमें, ग्रिड की उन सेल की संख्या को ध्यान में रखा गया है जिन पर विजेट को रखना है:
| सेल की संख्या (चौड़ाई x ऊंचाई) | पोर्ट्रेट मोड में उपलब्ध साइज़ (डीपी) | लैंडस्केप मोड में उपलब्ध साइज़ (डीपी) |
|---|---|---|
| 1x1 | 57x102dp | 127x51dp |
| 2x1 | 130x102dp | 269x51dp |
| 3x1 | 203x102dp | 412x51dp |
| 4x1 | 276x102dp | 554x51dp |
| 5x1 | 349x102dp | 697x51dp |
| 5x2 | 349x220dp | 697x117dp |
| 5x3 | 349x337dp | 697x184dp |
| 5x4 | 349x455dp | 697x250dp |
| ... | ... | ... |
| n x m | (73n - 16) x (118m - 16) | (142n - 15) x (66m - 15) |
minWidth, minResizeWidth, और maxResizeWidth एट्रिब्यूट के लिए दी गई वैल्यू के बारे में बताने के लिए, पोर्ट्रेट मोड के सेल साइज़ का इस्तेमाल करें. इसी तरह, लैंडस्केप मोड में सेल के साइज़ का इस्तेमाल करके, minHeight, minResizeHeight, और maxResizeHeight एट्रिब्यूट के लिए दी गई वैल्यू के बारे में बताएं.
ऐसा इसलिए होता है, क्योंकि पोर्ट्रेट मोड में सेल की चौड़ाई, लैंडस्केप मोड की तुलना में कम होती है. इसी तरह, लैंडस्केप मोड में सेल की ऊंचाई, पोर्ट्रेट मोड की तुलना में कम होती है.
उदाहरण के लिए, अगर आपको Google Pixel 4 पर अपने विजेट की चौड़ाई को एक सेल तक कम करना है, तो आपको minResizeWidth को ज़्यादा से ज़्यादा 56dp पर सेट करना होगा. इससे यह पक्का किया जा सकेगा कि minResizeWidth एट्रिब्यूट की वैल्यू 57dp से कम है. ऐसा इसलिए, क्योंकि पोर्ट्रेट मोड में सेल की चौड़ाई कम से कम 57dp होती है.
इसी तरह, अगर आपको एक ही डिवाइस पर एक सेल में अपने विजेट की ऊंचाई को फिर से साइज़ करने की सुविधा चाहिए, तो आपको अपने minResizeHeight को ज़्यादा से ज़्यादा 50dp पर सेट करना होगा. इससे यह पक्का किया जा सकेगा कि minResizeHeight एट्रिब्यूट की वैल्यू 51dp से कम है. ऐसा इसलिए, क्योंकि लैंडस्केप मोड में एक सेल की ऊंचाई कम से कम 51dp होती है.
हर विजेट का साइज़, minResizeWidth/minResizeHeight और maxResizeWidth/maxResizeHeight एट्रिब्यूट के बीच की साइज़ रेंज के हिसाब से बदला जा सकता है. इसका मतलब है कि विजेट को इनके बीच की किसी भी साइज़ रेंज के हिसाब से अडजस्ट किया जा सकता है.
उदाहरण के लिए, प्लेसमेंट पर विजेट का डिफ़ॉल्ट साइज़ सेट करने के लिए, इन एट्रिब्यूट को सेट किया जा सकता है:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:targetCellWidth="3" android:targetCellHeight="2" android:minWidth="180dp" android:minHeight="110dp"> </appwidget-provider>
इसका मतलब है कि विजेट का डिफ़ॉल्ट साइज़ 3x2 सेल है. यह targetCellWidth और targetCellHeight एट्रिब्यूट से तय होता है. इसके अलावा, Android 11 या इससे पहले के वर्शन वाले डिवाइसों के लिए, यह 180×110dp है. यह minWidth और minHeight एट्रिब्यूट से तय होता है. दूसरे मामले में, डिवाइस के हिसाब से सेल का साइज़ अलग-अलग हो सकता है.
इसके अलावा, अपने विजेट के लिए काम करने वाले साइज़ की रेंज सेट करने के लिए, इन एट्रिब्यूट को सेट किया जा सकता है:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minResizeWidth="180dp" android:minResizeHeight="110dp" android:maxResizeWidth="530dp" android:maxResizeHeight="450dp"> </appwidget-provider>
ऊपर दिए गए एट्रिब्यूट के मुताबिक, विजेट की चौड़ाई को 180 डीपी से 530 डीपी तक और ऊंचाई को 110 डीपी से 450 डीपी तक बदला जा सकता है. इसके बाद, विजेट का साइज़ 3x2 से 5x2 सेल तक बदला जा सकता है. हालांकि, इसके लिए ये शर्तें पूरी होनी चाहिए:
- डिवाइस में 5x4 ग्रिड हो.
- डीपीएस में उपलब्ध साइज़ और सेल की संख्या के बीच मैपिंग, इस पेज पर मौजूद कम से कम डाइमेंशन का अनुमान दिखाने वाली टेबल के मुताबिक होती है.
- विजेट, उस साइज़ रेंज के हिसाब से अपने-आप अडजस्ट हो जाता है.
val smallView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_small) val mediumView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_medium) val largeView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_large) val viewMapping: Map<SizeF, RemoteViews> = mapOf( SizeF(180f, 110f) to smallView, SizeF(270f, 110f) to mediumView, SizeF(270f, 280f) to largeView ) appWidgetManager.updateAppWidget(appWidgetId, RemoteViews(viewMapping))
मान लें कि विजेट, ऊपर दिए गए कोड स्निपेट में तय किए गए रिस्पॉन्सिव लेआउट का इस्तेमाल करता है. इसका मतलब है कि R.layout.widget_weather_forecast_small के तौर पर तय किया गया लेआउट, 180 डीपी (minResizeWidth) x 110 डीपी (minResizeHeight) से लेकर 269x279 डीपी (अगले कटऑफ़ पॉइंट - 1) तक इस्तेमाल किया जाता है. इसी तरह,
R.layout.widget_weather_forecast_medium का इस्तेमाल 270x110dp से 270x279dp तक किया जाता है,
और R.layout.widget_weather_forecast_large का इस्तेमाल 270x280dp से 530dp (maxResizeWidth) x 450dp (maxResizeHeight) तक किया जाता है.
उपयोगकर्ता के विजेट का साइज़ बदलने पर, उसकी बनावट बदल जाती है, ताकि वह सेल के हर साइज़ के हिसाब से अडजस्ट हो सके. इसे यहां दिए गए उदाहरणों में दिखाया गया है.
R.layout.widget_weather_forecast_small.
R.layout.widget_weather_forecast_medium.
R.layout.widget_weather_forecast_medium.
R.layout.widget_weather_forecast_large.
R.layout.widget_weather_forecast_large.