एक नज़र में जानकारी देखने की सुविधा की मदद से ऐप्लिकेशन का विजेट बनाना

यहां, Glance की मदद से, ऐप्लिकेशन का सामान्य विजेट बनाने का तरीका बताया गया है.

मेनिफ़ेस्ट में AppWidget का एलान करना

सेटअप के चरण पूरे करने के बाद, अपने ऐप्लिकेशन में AppWidget और उसके मेटाडेटा का एलान करें.

  1. GlanceAppWidgetReceiver से AppWidget रिसीवर को बढ़ाएं:

    class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
        override val glanceAppWidget: GlanceAppWidget = TODO("Create GlanceAppWidget")
    }

  2. AndroidManifest.xml फ़ाइल और उससे जुड़ी मेटाडेटा फ़ाइल में, ऐप्लिकेशन के विजेट की सेवा देने वाले को रजिस्टर करें:

        <receiver android:name=".glance.MyReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/my_app_widget_info" />
    </receiver>
    

AppWidgetProviderInfo मेटाडेटा जोड़ना

इसके बाद, विजेट बनाने की गाइड में दिया गया तरीका अपनाएं. इससे, @xml/my_app_widget_info फ़ाइल में, ऐप्लिकेशन विजेट की जानकारी बनाई और तय की जा सकेगी.

Glance के लिए, सिर्फ़ इतना अंतर है कि इसमें initialLayout एक्सएमएल नहीं होता. हालांकि, आपको इसे तय करना होगा. लाइब्रेरी में दिए गए, पहले से तय लोडिंग लेआउट का इस्तेमाल किया जा सकता है:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/glance_default_loading_layout">
</appwidget-provider>

AppWidgetProviderInfo एक्सएमएल का एलान करना

AppWidgetProviderInfo ऑब्जेक्ट, आपके विजेट की ज़रूरी क्वालिटी तय करता है. एक्सएमएल मेटाडेटा रिसॉर्स फ़ाइल (res/xml/my_app_widget_info.xml) में, <appwidget-provider> एलिमेंट के अंदर AppWidgetProviderInfo तय करें:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:targetCellWidth="1"
    android:targetCellHeight="1"
    android:maxResizeWidth="250dp"
    android:maxResizeHeight="120dp"
    android:updatePeriodMillis="86400000"
    android:description="@string/example_appwidget_description"
    android:previewLayout="@layout/example_appwidget_preview"
    android:initialLayout="@layout/glance_default_loading_layout"
    android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen"
    android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>

विजेट के साइज़ से जुड़े एट्रिब्यूट

डिफ़ॉल्ट होम स्क्रीन, विजेट को अपनी विंडो में, सेल के ग्रिड के आधार पर रखती है. इन सेल की लंबाई और चौड़ाई तय होती है. ज़्यादातर होम स्क्रीन पर, विजेट सिर्फ़ ऐसे साइज़ में दिखते हैं जो ग्रिड सेल के इंटिजर मल्टीपल होते हैं. उदाहरण के लिए, दो सेल हॉरिज़ॉन्टल और तीन सेल वर्टिकल.

विजेट के साइज़ से जुड़े एट्रिब्यूट की मदद से, अपने विजेट के लिए डिफ़ॉल्ट साइज़ तय किया जा सकता है. साथ ही, विजेट के साइज़ की निचली और ऊपरी सीमा तय की जा सकती है. इस संदर्भ में, विजेट का डिफ़ॉल्ट साइज़ वह साइज़ होता है जो विजेट को पहली बार होम स्क्रीन पर जोड़ने पर दिखता है.

यहां दी गई टेबल में, विजेट के साइज़ से जुड़े <appwidget-provider> एट्रिब्यूट के बारे में बताया गया है:

एट्रिब्यूट और जानकारी
targetCellWidth और targetCellHeight (Android 12), minWidth और minHeight
  • Android 12 से, targetCellWidth और targetCellHeight एट्रिब्यूट, ग्रिड सेल के हिसाब से विजेट का डिफ़ॉल्ट साइज़ तय करते हैं. Android 11 और इससे पहले के वर्शन में, इन एट्रिब्यूट को अनदेखा किया जाता है. साथ ही, अगर होम स्क्रीन पर ग्रिड-आधारित लेआउट की सुविधा नहीं है, तो इन्हें अनदेखा किया जा सकता है.
  • The minWidth और minHeight एट्रिब्यूट, dp में विजेट का डिफ़ॉल्ट साइज़ तय करते हैं. अगर किसी विजेट की कम से कम चौड़ाई या लंबाई की वैल्यू, सेल के डाइमेंशन से मेल नहीं खाती तो वैल्यू को सबसे नज़दीकी सेल साइज़ में राउंड अप कर दिया जाता है.
हमारा सुझाव है कि एट्रिब्यूट के दोनों सेट—targetCellWidth और targetCellHeight, और minWidth और minHeight—तय करें, ताकि अगर उपयोगकर्ता के डिवाइस पर targetCellWidth और targetCellHeight की सुविधा नहीं है, तो आपका ऐप्लिकेशन minWidth और minHeight का इस्तेमाल कर सके. अगर सुविधा उपलब्ध है, तो targetCellWidth और targetCellHeight एट्रिब्यूट के बजाय minWidth और minHeight एट्रिब्यूट का इस्तेमाल किया जाता है.
minResizeWidth और minResizeHeight विजेट का कम से कम साइज़ तय करें. इन वैल्यू से, उस साइज़ के बारे में पता चलता है जिससे कम होने पर, विजेट को पढ़ा नहीं जा सकता या उसका इस्तेमाल नहीं किया जा सकता. इन एट्रिब्यूट का इस्तेमाल करके, उपयोगकर्ता विजेट का साइज़, डिफ़ॉल्ट विजेट साइज़ से छोटा कर सकता है. अगर minResizeWidth एट्रिब्यूट की वैल्यू, minWidth से ज़्यादा है या हॉरिज़ॉन्टल साइज़ बदलने की सुविधा चालू नहीं है, तो इसे अनदेखा कर दिया जाता है. देखेंresizeMode. इसी तरह, अगर minResizeHeight एट्रिब्यूट की वैल्यू, minHeight से ज़्यादा है या वर्टिकल साइज़ बदलने की सुविधा चालू नहीं है, तो इसे अनदेखा कर दिया जाता है.
maxResizeWidth और maxResizeHeight विजेट का ज़्यादा से ज़्यादा साइज़ तय करें. अगर वैल्यू, ग्रिड सेल के डाइमेंशन का मल्टीपल नहीं हैं, तो उन्हें सबसे नज़दीकी सेल साइज़ में राउंड अप कर दिया जाता है. अगर maxResizeWidth एट्रिब्यूट की वैल्यू, minWidth से कम है या हॉरिज़ॉन्टल साइज़ बदलने की सुविधा चालू नहीं है, तो इसे अनदेखा कर दिया जाता है. resizeMode देखें. इसी तरह, अगर maxResizeHeight एट्रिब्यूट की वैल्यू, minHeight से कम है या वर्टिकल साइज़ बदलने की सुविधा चालू नहीं है, तो इसे अनदेखा कर दिया जाता है. Android 12 में यह सुविधा जोड़ी गई है.
resizeMode इससे उन नियमों के बारे में पता चलता है जिनके हिसाब से विजेट का साइज़ बदला जा सकता है. इस एट्रिब्यूट का इस्तेमाल करके, होम स्क्रीन पर मौजूद विजेट का साइज़ हॉरिज़ॉन्टल, वर्टिकल, या दोनों ऐक्सिस पर बदला जा सकता है. उपयोगकर्ता, विजेट को दबाकर रखता है, ताकि उसके साइज़ बदलने के हैंडल दिखें. इसके बाद, लेआउट ग्रिड पर उसका साइज़ बदलने के लिए, हॉरिज़ॉन्टल या वर्टिकल हैंडल को खींचता है. resizeMode एट्रिब्यूट की वैल्यू में horizontal, vertical, और none शामिल हैं. किसी विजेट को हॉरिज़ॉन्टल और वर्टिकल, दोनों तरह से साइज़ बदलने की अनुमति देने के लिए, इस्तेमाल करें horizontal|vertical.

उदाहरण

यहां दी गई टेबल में मौजूद एट्रिब्यूट, विजेट के साइज़ पर कैसे असर डालते हैं, यह दिखाने के लिए, मान लें कि ये स्पेसिफ़िकेशन दिए गए हैं:

  • ग्रिड सेल की चौड़ाई 30 dp और लंबाई 50 dp है.
  • यहां एट्रिब्यूट का स्पेसिफ़िकेशन दिया गया है:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="80dp"
    android:minHeight="80dp"
    android:targetCellWidth="2"
    android:targetCellHeight="2"
    android:minResizeWidth="40dp"
    android:minResizeHeight="40dp"
    android:maxResizeWidth="120dp"
    android:maxResizeHeight="120dp"
    android:resizeMode="horizontal|vertical" />

Android 12 से:

targetCellWidth और targetCellHeight एट्रिब्यूट का इस्तेमाल, विजेट के डिफ़ॉल्ट साइज़ के तौर पर करें.

डिफ़ॉल्ट रूप से, विजेट का साइज़ 2x2 होता है. विजेट का साइज़ 2x1 से 4x3 तक बदला जा सकता है.

Android 11 और इससे पहले के वर्शन:

विजेट का डिफ़ॉल्ट साइज़ कैलकुलेट करने के लिए, minWidth और minHeight एट्रिब्यूट का इस्तेमाल करें.

डिफ़ॉल्ट चौड़ाई = Math.ceil(80 / 30) = 3

डिफ़ॉल्ट लंबाई = Math.ceil(80 / 50) = 2

डिफ़ॉल्ट रूप से, विजेट का साइज़ 3x2 होता है. विजेट का साइज़ 2x1 से फुल स्क्रीन तक बदला जा सकता है.

विजेट के अन्य एट्रिब्यूट

यहां दी गई टेबल में, विजेट के साइज़ के अलावा अन्य क्वालिटी से जुड़े <appwidget-provider> एट्रिब्यूट के बारे में बताया गया है.

एट्रिब्यूट और जानकारी
updatePeriodMillis इससे यह तय होता है कि विजेट फ़्रेमवर्क, GlanceAppWidgetReceiver से, onUpdate() कॉलबैक तरीके को कॉल करके, कितनी बार अपडेट का अनुरोध करता है. हमारा सुझाव है कि बैटरी बचाने के लिए, अपडेट कम से कम बार करें. एक घंटे में एक बार से ज़्यादा अपडेट न करें. ज़्यादा जानकारी के लिए, Glance में स्टेट मैनेजमेंट के तहत, विजेट को कब अपडेट करें सेक्शन देखें.
initialLayout यह उस लेआउट रिसॉर्स की ओर इशारा करता है जो Glance यूज़र इंटरफ़ेस (यूआई) कंपोज़िशन के रेंडर होने से पहले, विजेट के लोडिंग लेआउट को तय करता है. लाइब्रेरी में दिए गए, पहले से तय लोडिंग लेआउट का इस्तेमाल किया जा सकता है: @layout/glance_default_loading_layout.
configure इससे उस कॉन्फ़िगरेशन गतिविधि के बारे में पता चलता है जो उपयोगकर्ता के विजेट जोड़ने पर लॉन्च होती है. ऐप्लिकेशन के विजेट को कॉन्फ़िगर करने की अनुमति देना गाइड देखें.
description इससे विजेट पिकर के लिए, आपके विजेट की जानकारी तय होती है. Android 12 में यह सुविधा जोड़ी गई है.
previewLayout (Android 12) और previewImage (Android 11 और इससे पहले के वर्शन)
  • Android 12 से, previewLayout एट्रिब्यूट, स्केलेबल झलक तय करता है. इसे एक्सएमएल लेआउट के तौर पर दिया जाता है, जो विजेट के डिफ़ॉल्ट साइज़ पर सेट होता है. आदर्श तौर पर, यह आपके डिज़ाइन लेआउट से मेल खाने वाली स्टैटिक एक्सएमएल मैपिंग की ओर इशारा करता है.
  • Android 11 या इससे पहले के वर्शन में, previewImage एट्रिब्यूट, विजेट की स्टैटिक इमेज ड्रॉएबल स्क्रीनशॉट तय करता है. यह विजेट पिकर में दिखता है.
हमारा सुझाव है कि दोनों को तय करें, ताकि आपका ऐप्लिकेशन पुराने प्लैटफ़ॉर्म पर भी ठीक से काम करे. नए प्लैटफ़ॉर्म (Android 15 और इसके बाद के वर्शन) के लिए, Kotlin में `GlanceAppWidget.providePreview` का इस्तेमाल करके, लाइव जनरेट की गई झलक तय की जा सकती हैं. जनरेट की गई झलकें गाइड देखें.
autoAdvanceViewId इससे विजेट के सबव्यू का व्यू आईडी तय होता है, जिसे विजेट का होस्ट अपने-आप आगे बढ़ाता है.
widgetCategory इससे यह तय होता है कि आपका विजेट, होम स्क्रीन (home_screen), लॉक स्क्रीन (keyguard) या दोनों पर दिख सकता है. Android 5.0 और इसके बाद के वर्शन के लिए, सिर्फ़ home_screen मान्य है.
widgetFeatures इससे विजेट की उन सुविधाओं के बारे में पता चलता है जिन्हें वह सपोर्ट करता है. उदाहरण के लिए, अगर आपके विजेट का कॉन्फ़िगरेशन ज़रूरी नहीं है, तो configuration_optional और reconfigurable, दोनों तय करें.

GlanceAppWidget तय करना

  1. एक नई क्लास बनाएं, जो GlanceAppWidget से एक्सटेंड होती है और provideGlance तरीके को ओवरराइड करती है. यह वह तरीका है जिससे विजेट को रेंडर करने के लिए ज़रूरी डेटा लोड किया जा सकता है:

    class MyAppWidget : GlanceAppWidget() {
    
        override suspend fun provideGlance(context: Context, id: GlanceId) {
    
            // In this method, load data needed to render the AppWidget.
            // Use `withContext` to switch to another thread for long running
            // operations.
    
            provideContent {
                // create your AppWidget here
                Text("Hello World")
            }
        }
    }

  2. GlanceAppWidgetReceiver पर, glanceAppWidget में इसे इंस्टैंशिएट करें:

    class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
    
        // Let MyAppWidgetReceiver know which GlanceAppWidget to use
        override val glanceAppWidget: GlanceAppWidget = MyAppWidget()
    }

अब आपने Glance का इस्तेमाल करके, AppWidget को कॉन्फ़िगर कर लिया है.

विजेट के ब्रॉडकास्ट को हैंडल करने के लिए, GlanceAppWidgetReceiver क्लास का इस्तेमाल करना

GlanceAppWidgetReceiver विजेट के ब्रॉडकास्ट और प्लैटफ़ॉर्म के स्टेट अपडेट को कोऑर्डिनेट करता है, AppWidgetProvider को बढ़ाकर. जब आपका विजेट अपडेट, मिटाया, चालू या बंद किया जाता है, तो इसे प्लैटफ़ॉर्म के इवेंट मिलते हैं. यह उन्हें Compose लाइफ़साइकल के अनुरोधों में बदलता है.

मेनिफ़ेस्ट में विजेट का एलान करना

AndroidManifest.xml फ़ाइल में, GlanceAppWidgetReceiver क्लास के सबक्लास को ब्रॉडकास्ट रिसीवर के तौर पर एलान करें:

<receiver android:name="MyReceiver"
          android:exported="false">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
               android:resource="@xml/my_app_widget_info" />
</receiver>

<receiver> एलिमेंट के लिए, android:name एट्रिब्यूट ज़रूरी है. इससे रिसीवर क्लास तय होती है. रिसीवर को <intent-filter> में, ACTION_APPWIDGET_UPDATE ब्रॉडकास्ट ऐक्शन स्वीकार करना होगा.

<meta-data> एलिमेंट के नाम को android.appwidget.provider के तौर पर तय करना होगा. साथ ही, android:resource एट्रिब्यूट को AppWidgetProviderInfo एक्सएमएल मेटाडेटा रिसॉर्स (@xml/my_app_widget_info) की ओर इशारा करना होगा.

GlanceAppWidgetReceiver क्लास लागू करना

Glance में, सीधे AppWidgetProvider के बजाय GlanceAppWidgetReceiver को बढ़ाया जाता है. इसे लागू करने के लिए, अपने रिसीवर को GlanceAppWidget इंस्टेंस से लिंक करें. GlanceAppWidgetReceiver में उपलब्ध प्राइमरी कॉलबैक, इस तरह काम करते हैं:

  • onUpdate(): कंपोज़िशन अपडेट को लागू करने के लिए, Glance इसे अपने-आप ओवरराइड करता है. अगर onUpdate को मैन्युअल तरीके से ओवरराइड किया जाता है, तो आपको कॉल करना होगा super.onUpdate , ताकि Glance, कंपोज़िशन थ्रेड को लॉन्च कर सके.
  • onAppWidgetOptionsChanged(): विजेट को पहली बार रखने या उसका साइज़ बदलने पर इसे कॉल किया जाता है. Glance, विकल्पों के बंडल में मौजूद आइटम को बैकग्राउंड में पढ़ता है, ताकि रनटाइम डाइमेंशन के आधार पर आपका लेआउट आसानी से अडजस्ट हो सके.
  • onDeleted(Context, IntArray): जब भी उपयोगकर्ता, विजेट के किसी खास इंस्टेंस को मिटाता है, तब इसे कॉल किया जाता है.
  • onEnabled(Context): जब आपके विजेट का पहला इंस्टेंस, सफलतापूर्वक बनाया जाता है, तब इसे ट्रिगर किया जाता है. ग्लोबल माइग्रेशन करने के लिए यह शानदार है.
  • onDisabled(Context): जब सेवा देने वाले का आखिरी ऐक्टिव इंस्टेंस हटाया जाता है, तब इसे कॉल किया जाता है.
  • onReceive(Context, Intent): यह प्लैटफ़ॉर्म के हर ब्रॉडकास्ट को, कॉलबैक के खास तरीकों से पहले इंटरसेप्ट करता है. आपको यह पक्का करना होगा कि आपके लिखे गए कस्टम रिसीवर लॉजिक में, super.onReceive(context, intent) को कॉल किया जाए. साथ ही, आपको कभी भी goAsync को कॉल नहीं करना चाहिए , क्योंकि Glance, काम को एसिंक्रोनस तरीके से अपने-आप रूट करता है.

विजेट के ब्रॉडकास्ट इंटेंट पाना

GlanceAppWidgetReceiver, प्लैटफ़ॉर्म के विजेट के ब्रॉडकास्ट के इन बुनियादी इंटेंट को फ़िल्टर और हैंडल करता है:

यूज़र इंटरफ़ेस (यूआई) बनाना

यहां दिए गए स्निपेट से पता चलता है कि यूज़र इंटरफ़ेस (यूआई) कैसे बनाया जाता है:

/* Import Glance Composables
 In the event there is a name clash with the Compose classes of the same name,
 you may rename the imports per https://kotlinlang.org/docs/packages.html#imports
 using the `as` keyword.

import androidx.glance.Button
import androidx.glance.layout.Column
import androidx.glance.layout.Row
import androidx.glance.text.Text
*/
class MyAppWidget : GlanceAppWidget() {

    override suspend fun provideGlance(context: Context, id: GlanceId) {
        // Load data needed to render the AppWidget.
        // Use `withContext` to switch to another thread for long running
        // operations.

        provideContent {
            // create your AppWidget here
            MyContent()
        }
    }

    @Composable
    private fun MyContent() {
        Column(
            modifier = GlanceModifier.fillMaxSize(),
            verticalAlignment = Alignment.Top,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(text = "Where to?", modifier = GlanceModifier.padding(12.dp))
            Row(horizontalAlignment = Alignment.CenterHorizontally) {
                Button(
                    text = "Home",
                    onClick = actionStartActivity<MyActivity>()
                )
                Button(
                    text = "Work",
                    onClick = actionStartActivity<MyActivity>()
                )
            }
        }
    }
}

ऊपर दिए गए कोड के सैंपल से ये काम होते हैं:

  • टॉप लेवल Column में, आइटम को वर्टिकल तरीके से एक के बाद एक रखा जाता है.
  • Column, उपलब्ध जगह के हिसाब से अपना साइज़ बढ़ाता है. इसके लिए, GlanceModifier का इस्तेमाल किया जाता है. साथ ही, यह अपने कॉन्टेंट को सबसे ऊपर (verticalAlignment) अलाइन करता है और हॉरिज़ॉन्टल तरीके से बीच में (horizontalAlignment) रखता है.
  • Column का कॉन्टेंट, लैम्डा का इस्तेमाल करके तय किया जाता है. यहां क्रम मायने रखता है.
    • Column में पहला आइटम, Text कॉम्पोनेंट है. इसमें 12.dp का पैडिंग है.
    • दूसरा आइटम, Row है. इसमें आइटम को हॉरिज़ॉन्टल तरीके से एक के बाद एक रखा जाता है. साथ ही, दो Buttons को हॉरिज़ॉन्टल तरीके से बीच में (horizontalAlignment) रखा जाता है. फ़ाइनल डिसप्ले, उपलब्ध जगह पर निर्भर करता है. यहां दी गई इमेज, इसका एक उदाहरण है:
destination_widget
पहली इमेज. यूज़र इंटरफ़ेस (यूआई) का एक उदाहरण.

कॉम्पोनेंट की जगह और साइज़ बदलने के लिए, अलाइनमेंट की वैल्यू बदली जा सकती हैं या अलग-अलग मॉडिफ़ायर वैल्यू (जैसे, पैडिंग) लागू की जा सकती हैं. हर क्लास के लिए कॉम्पोनेंट, पैरामीटर, और उपलब्ध मॉडिफ़ायर की पूरी सूची देखने के लिए, रेफ़रंस दस्तावेज़ देखें.

गोल कोने लागू करना

Android 12 में, ऐप्लिकेशन के विजेट के कोनों के रेडियस को डाइनैमिक तरीके से पसंद के मुताबिक बनाने के लिए, सिस्टम पैरामीटर जोड़े गए हैं:

  • system_app_widget_background_radius: इससे विजेट के बैकग्राउंड कंटेनर के कोनों का रेडियस तय होता है. यह 28 dp से ज़्यादा नहीं हो सकता.
  • इनर रेडियस: कॉन्टेंट को क्लिप होने से बचाने के लिए, सिस्टम के बैकग्राउंड आउटलाइन के आधार पर, अपने इनर कॉन्टेंट के लिए आनुपातिक रेडियस कैलकुलेट करें: systemRadiusValue - widgetPadding

Glance में, GlanceModifier.cornerRadius(android.R.dimen.system_app_widget_background_radius) का इस्तेमाल करके, कंपोज़िशन में कोनों के रेडियस के साइज़ की प्रॉपर्टी को डाइनैमिक तरीके से लागू किया जा सकता है.

Android 11 (एपीआई लेवल 30) या इससे पहले के वर्शन वाले डिवाइसों पर बैकवर्ड कंपैटिबिलिटी के लिए, कस्टम एट्रिब्यूट और कस्टम थीम रिसॉर्स फ़ॉलबैक लागू करें:

  • /values/attrs.xml

    <resources>
    <attr name="backgroundRadius" format="dimension" />
    </resources>
    
  • /values/styles.xml

    <resources>
    <style name="MyWidgetTheme">
      <item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
    </style>
    </resources>
    
  • /values-31/styles.xml

    <resources>
    <style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
      <item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
    </style>
    </resources>
    
  • /drawable/my_widget_background.xml

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="?attr/backgroundRadius" />
    </shape>