इस पेज पर, 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
...
android:targetCellWidth="3"
android:targetCellHeight="2"
android:maxResizeWidth="250dp"
android:maxResizeHeight="110dp">
</appwidget-provider>
रिस्पॉन्सिव लेआउट देना
अगर विजेट के साइज़ के हिसाब से लेआउट में बदलाव करना है, तो हमारा सुझाव है कि लेआउट का एक छोटा सेट बनाएं. हर लेआउट, साइज़ की एक रेंज के लिए मान्य होता है. अगर ऐसा नहीं किया जा सकता, तो दूसरा विकल्प यह है कि रनटाइम में विजेट के सटीक साइज़ के हिसाब से लेआउट दिए जाएं. इसके बारे में, इस पेज पर बताया गया है.
इस सुविधा से, बेहतर तरीके से स्केल किया जा सकता है और सिस्टम की परफ़ॉर्मेंस भी बेहतर होती है. ऐसा इसलिए, क्योंकि सिस्टम को हर बार अलग-अलग साइज़ में विजेट दिखाने के लिए, ऐप्लिकेशन को चालू नहीं करना पड़ता.
यहां दिए गए कोड के उदाहरण में, लेआउट की सूची देने का तरीका बताया गया है.
Kotlin
override fun onUpdate(...) { val smallView = ... val tallView = ... val wideView = ... 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) }
Java
@Override public void onUpdate(...) { RemoteViews smallView = ...; RemoteViews tallView = ...; RemoteViews wideView = ...; Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>(); viewMapping.put(new SizeF(150f, 100f), smallView); viewMapping.put(new SizeF(150f, 200f), tallView); viewMapping.put(new SizeF(215f, 100f), wideView); RemoteViews remoteViews = new RemoteViews(viewMapping); appWidgetManager.updateAppWidget(id, remoteViews); }
मान लें कि विजेट में ये एट्रिब्यूट हैं:
<appwidget-provider
android:minResizeWidth="160dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="250dp"
android:maxResizeHeight="200dp">
</appwidget-provider>
ऊपर दिए गए कोड स्निपेट का मतलब यह है:
smallView, 160dp (minResizeWidth) × 110dp (minResizeHeight) से लेकर 160dp × 199dp (अगला कटऑफ़ पॉइंट - 1dp) तक के साइज़ के साथ काम करता है.tallView, 160dp × 200dp से लेकर 214dp (अगला कटऑफ़ पॉइंट - 1) × 200dp तक के साइज़ के साथ काम करता है.wideView, 215dp × 110dp (minResizeHeight) से लेकर 250dp (maxResizeWidth) × 200dp (maxResizeHeight) तक के साइज़ के साथ काम करता है.
आपका विजेट, minResizeWidth × minResizeHeight से लेकर maxResizeWidth × maxResizeHeight तक के साइज़ की रेंज के साथ काम करना चाहिए. इस रेंज में, लेआउट बदलने के लिए कटऑफ़ पॉइंट तय किया जा सकता है.
सटीक लेआउट देना
अगर रिस्पॉन्सिव लेआउट का छोटा सेट बनाना मुमकिन नहीं है, तो इसके बजाय, विजेट के साइज़ के हिसाब से अलग-अलग लेआउट दिए जा सकते हैं. आम तौर पर, फ़ोन के लिए दो साइज़ (पोर्ट्रेट और लैंडस्केप मोड) और फ़ोल्ड किए जा सकने वाले डिवाइसों के लिए चार साइज़ होते हैं.
इस समाधान को लागू करने के लिए, आपके ऐप्लिकेशन को ये चरण पूरे करने होंगे:
AppWidgetProvider.onAppWidgetOptionsChanged()को ओवरलोड करें. साइज़ का सेट बदलने पर, इसे कॉल किया जाता है.AppWidgetManager.getAppWidgetOptions()को कॉल करें, इससे, साइज़ वालाBundleमिलता है.Bundleसे,AppWidgetManager.OPTION_APPWIDGET_SIZESकुंजी को ऐक्सेस करें.
यहां दिए गए कोड के उदाहरण में, सटीक लेआउट देने का तरीका बताया गया है.
Kotlin
override fun onAppWidgetOptionsChanged( context: Context, appWidgetManager: AppWidgetManager, id: Int, newOptions: Bundle? ) { super.onAppWidgetOptionsChanged(context, appWidgetManager, id, newOptions) // Get the new sizes. val sizes = newOptions?.getParcelableArrayList<SizeF>( AppWidgetManager.OPTION_APPWIDGET_SIZES ) // 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 { }
Java
@Override public void onAppWidgetOptionsChanged( Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); // Get the new sizes. ArrayList<SizeF> sizes = newOptions.getParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES); // Check that the list of sizes is provided by the launcher. if (sizes == null || sizes.isEmpty()) { return; } // Map the sizes to the RemoteViews that you want. Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>(); for (SizeF size : sizes) { viewMapping.put(size, createRemoteViews(size)); } RemoteViews remoteViews = new RemoteViews(viewMapping); appWidgetManager.updateAppWidget(id, remoteViews); } // Create the RemoteViews for the given size. private RemoteViews createRemoteViews(SizeF size) { }
अपने विजेट के लिए साइज़ तय करना
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
android:targetCellWidth="3"
android:targetCellHeight="2"
android:minWidth="180dp"
android:minHeight="110dp">
</appwidget-provider>
इसका मतलब है कि विजेट का डिफ़ॉल्ट साइज़ 3x2 सेल है. यह जानकारी, targetCellWidth और targetCellHeight एट्रिब्यूट से मिलती है. वहीं, Android 11 या उससे पहले के वर्शन पर चलने वाले डिवाइसों के लिए, minWidth और minHeight से 180×110dp की जानकारी मिलती है. दूसरे मामले में, सेल में साइज़, डिवाइस के हिसाब से अलग-अलग हो सकता है.
इसके अलावा, अपने विजेट के लिए काम करने वाली साइज़ रेंज सेट करने के लिए, ये एट्रिब्यूट सेट किए जा सकते हैं:
<appwidget-provider
android:minResizeWidth="180dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="530dp"
android:maxResizeHeight="450dp">
</appwidget-provider>
ऊपर दिए गए एट्रिब्यूट के मुताबिक, विजेट की चौड़ाई को 180dp से 530dp तक और ऊंचाई को 110dp से 450dp तक बदला जा सकता है. इसके बाद, विजेट का साइज़ 3x2 सेल से 5x2 सेल तक बदला जा सकता है. हालांकि, इसके लिए ये शर्तें पूरी होनी चाहिए:
- डिवाइस में 5x4 ग्रिड हो.
- सेल की संख्या और dps में उपलब्ध साइज़ के बीच मैपिंग , इस पेज पर कम से कम डाइमेंशन के अनुमान दिखाने वाली टेबल के मुताबिक हो.
- विजेट, उस साइज़ रेंज के हिसाब से अडजस्ट हो.
Kotlin
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))
Java
RemoteViews smallView = new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_small); RemoteViews mediumView = new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_medium); RemoteViews largeView = new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_large); Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>(); viewMapping.put(new SizeF(180f, 110f), smallView); viewMapping.put(new SizeF(270f, 110f), mediumView); viewMapping.put(new SizeF(270f, 280f), largeView); RemoteViews remoteViews = new RemoteViews(viewMapping); appWidgetManager.updateAppWidget(id, remoteViews);
मान लें कि विजेट, ऊपर दिए गए कोड स्निपेट में तय किए गए रिस्पॉन्सिव लेआउट का इस्तेमाल करता है. इसका मतलब है कि R.layout.widget_weather_forecast_small के तौर पर तय किया गया लेआउट, 180dp (minResizeWidth) x 110dp (minResizeHeight) से लेकर 269x279dp (अगले कटऑफ़ पॉइंट - 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.