Glance-এর সাহায্যে অ্যাপ উইজেট তৈরি করা

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 XML নেই, তবে আপনাকে একটি সংজ্ঞায়িত করতে হবে। আপনি লাইব্রেরিতে দেওয়া পূর্বনির্ধারিত লোডিং লেআউট ব্যবহার করতে পারেন:

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

AppWidgetProviderInfo XML ঘোষণা করা

AppWidgetProviderInfo অবজেক্ট আপনার উইজেটের প্রয়োজনীয় কোয়ালিটি নির্ধারণ করে। আপনার XML মেটাডেটা রিসোর্স ফাইলে AppWidgetProviderInfo সংজ্ঞায়িত করুন (res/xml/my_app_widget_info.xml) <appwidget-provider> এলিমেন্টের মধ্যে:

<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 এবং তার আগের ভার্সনে এইসব অ্যাট্রিবিউট এড়িয়ে যাওয়া হয় এবং হোম স্ক্রিনে গ্রিড-ভিত্তিক লেআউট কাজ না করলে, এড়িয়ে যাওয়া যেতে পারে।
  • 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 ব্যবহার করুন।

উদাহরণ

আগের সারণীতে উল্লেখ করা অ্যাট্রিবিউটগুলি কীভাবে উইজেটের সাইজকে প্রভাবিত করে তা বোঝাতে, নিম্নলিখিত স্পেসিফিকেশনগুলি ধরে নিন:

  • গ্রিড সেলের প্রস্থ ৩০ dp এবং উচ্চতা ৫০ 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 অ্যাট্রিবিউট ব্যবহার করুন।

ডিফল্ট হিসেবে উইজেটের সাইজ হল ২x২। উইজেটের সাইজ কমিয়ে 2x1 বা বাড়িয়ে 4x3 করা যেতে পারে।

Android 11 ও তার আগের যেকোনও ভার্সনে:

উইজেটের ডিফল্ট সাইজ গণনা করতে minWidth এবং minHeight অ্যাট্রিবিউট ব্যবহার করুন।

ডিফল্ট প্রস্থ = Math.ceil(80 / 30) = ৩

ডিফল্ট উচ্চতা = Math.ceil(80 / 50) = ২

ডিফল্ট হিসেবে উইজেটের সাইজ হল ৩x২। উইজেটটি ২x১ পর্যন্ত ছোট বা ফুল স্ক্রিন পর্যন্ত বড় করা যেতে পারে।

অতিরিক্ত উইজেট অ্যাট্রিবিউট

নিম্নলিখিত সারণীতে উইজেটের সাইজ ছাড়া অন্যান্য কোয়ালিটি সম্পর্কিত <appwidget-provider>টি অ্যাট্রিবিউট বর্ণনা করা হয়েছে।

অ্যাট্রিবিউট ও বিবরণ
updatePeriodMillis onUpdate() কলব্যাক পদ্ধতি কল করার মাধ্যমে GlanceAppWidgetReceiver থেকে উইজেট ফ্রেমওয়ার্ক কত ঘন ঘন আপডেট করার অনুরোধ করে তা নির্ধারণ করে। ব্যাটারি সাশ্রয় করতে, আমরা যতটা সম্ভব কম ঘন ঘন আপডেট করার সাজেশন দিই— ঘণ্টায় একবারের বেশি নয়। আরও বিবরণের জন্য, Glance স্টেট ম্যানেজমেন্টে কখন উইজেট আপডেট করতে হবে বিভাগটি দেখুন।
initialLayout লেআউট রিসোর্সকে পয়েন্ট করে যা Glance UI কম্পোজিশন রেন্ডার করার আগে উইজেটের লোডিং লেআউটকে সংজ্ঞায়িত করে। আপনি লাইব্রেরিতে দেওয়া আগে থেকে নির্ধারিত লোডিং লেআউট ব্যবহার করতে পারেন: @layout/glance_default_loading_layout।
configure ব্যবহারকারী উইজেট যোগ করলে যে কনফিগারেশন অ্যাক্টিভিটি চালু হয় তা নির্ধারণ করে। ব্যবহারকারীদের অ্যাপ উইজেট কনফিগার করার অনুমতি দিন নির্দেশিকা দেখুন।
description আপনার উইজেটের জন্য দেখানোর জন্য উইজেট পিকারের বিবরণ নির্দিষ্ট করে। Android 12-এ চালু করা হয়েছে।
previewLayout (Android 12) এবং previewImage (Android 11 ও তার আগের যেকোনও ভার্সন)
  • Android 12 থেকে শুরু করে, previewLayout অ্যাট্রিবিউট একটি স্কেলেবল প্রিভিউ নির্দিষ্ট করে, যা আপনি উইজেটের ডিফল্ট সাইজে সেট করা XML লেআউট হিসেবে প্রদান করেন। সাধারণত, এটি আপনার ডিজাইন লেআউটের সাথে মেলে এমন একটি স্ট্যাটিক XML ম্যাপিংকে নির্দেশ করে।
  • Android 11 বা তার আগের ভার্সনে, previewImage অ্যাট্রিবিউট উইজেট পিকারে উইজেটটি কেমন দেখায় তার একটি স্ট্যাটিক ইমেজ ড্রয়েবল স্ক্রিনশট নির্দিষ্ট করে।
আমরা দুটিই উল্লেখ করার সাজেশন দিই যাতে আপনার অ্যাপ পুরনো প্ল্যাটফর্মেও ভালভাবে কাজ করে। নতুন প্ল্যাটফর্মের (Android 15+) জন্য, আপনি `GlanceAppWidget.providePreview` ব্যবহার করে Kotlin-এ লাইভ জেনারেট করা প্রিভিউ সংজ্ঞায়িত করতে পারবেন। জেনারেট করা প্রিভিউ সংক্রান্ত গাইড দেখুন।
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 কনফিগার করেছেন।

সাইজ বাকেট জুড়ে উইজেট ইমেজ মেমরি ম্যানেজ করুন

আপনার উইজেট বিটম্যাপ বা content:// ইমেজ URI দেখালে, নিম্নলিখিত কাজগুলি করে মোট সিরিয়ালাইজ করা RemoteViews ইমেজ মেমরি সিস্টেমের সীমার (6 * width * height বাইট, Android 17 এবং তার পরবর্তী ভার্সনে IllegalArgumentException-এর মাধ্যমে এনফোর্স করা) মধ্যে রাখুন:

  • provideContent-এর আগে শেয়ার করা বিটম্যাপ ডিকোড করুন: আপনার উইজেট SizeMode.Responsive বা SizeMode.Exact ব্যবহার করলে, Glance প্রতিটি DpSize বাকেটের জন্য একবার provideContent ল্যাম্বডা রান করে। provideContent-এর মধ্যে Bitmap ডিকোড করলে প্রতিটি বাকেটের জন্য আলাদা Bitmap ইনস্ট্যান্স বরাদ্দ হয়, যার ফলে RemoteViews.mBitmapCache-এ মেমরির ব্যবহার বহুগুণ বেড়ে যায়। provideGlance-এর মধ্যে একবার ডাউনস্যাম্পেল করা বিটম্যাপ (অস্বচ্ছ ছবির জন্য Bitmap.Config.RGB_565) ডিকোড করুন provideContent-এর আগে যাতে সব বাকেট একটিই Bitmap রেফারেন্স শেয়ার করে।
  • ম্যাচিং ImageProvider ইমপোর্ট ব্যবহার করুন: Jetpack Glance দুটি প্যাকেজ জুড়ে দুটি আলাদা ImageProvider ওভারলোড প্রদান করে:

    • ইন-মেমরি ImageProvider(bitmap: Bitmap) বা ড্রয়েবল রিসোর্স ImageProvider(resId: Int) পাস করার সময় import androidx.glance.ImageProvider ব্যবহার করুন।
    • URI পাস করার সময় import androidx.glance.appwidget.ImageProvider ব্যবহার করুন ImageProvider(uri: Uri)। FileProvider URI-এর মাধ্যমে ক্যাশে করা ফাইল পরিবেশন করার সময়, প্রতিটি ইনস্টল করা Intent.CATEGORY_HOME লঞ্চার প্যাকেজে Intent.FLAG_GRANT_READ_URI_PERMISSION মঞ্জুর করুন যাতে হোস্ট ছবিটি রেন্ডার করতে পারে।

উইজেট ব্রডকাস্ট ম্যানেজ করতে GlanceAppWidgetReceiver ক্লাস ব্যবহার করুন

GlanceAppWidgetReceiver কোঅর্ডিনেট উইজেট ব্রডকাস্ট এবং প্ল্যাটফর্ম স্টেট অন্তর্নিহিত AppWidgetProvider বাড়িয়ে আপডেট করে। আপনার উইজেট আপডেট, মুছে ফেলা, চালু বা বন্ধ করা হলে এটি প্ল্যাটফর্ম ইভেন্ট পায়, সেগুলিকে কম্পোজ লাইফসাইকেল অনুরোধে অনুবাদ করে।

ম্যানিফেস্টে উইজেট ঘোষণা করা

আপনার 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 মেটাডেটা রিসোর্স (@xml/my_app_widget_info) পয়েন্ট করতে হবে।

GlanceAppWidgetReceiver ক্লাস প্রয়োগ করুন

Glance-এ, আপনি সরাসরি AppWidgetProvider-এর পরিবর্তে GlanceAppWidgetReceiver এক্সটেন্ড করেন। আপনার রিসিভারকে আপনার GlanceAppWidget ইনস্ট্যান্সের সাথে লিঙ্ক করে এটি প্রয়োগ করুন। GlanceAppWidgetReceiver-এ উপলভ্য প্রাথমিক কলব্যাক নিম্নলিখিতভাবে কাজ করে:

  • onUpdate(): কম্পোজিশন আপডেট কার্যকর করতে Glance-এর মাধ্যমে অটোমেটিক ওভাররাইড করা হয়। আপনি ম্যানুয়ালি onUpdate ওভাররাইড করলে, Glance-কে কম্পোজিশন থ্রেড সফলভাবে লঞ্চ করার অনুমতি দিতে, আপনাকে অবশ্যই super.onUpdate কল করতে হবে।
  • onAppWidgetOptionsChanged(): উইজেট প্রথমবার প্লেস করা বা ছোট বড় করার সময় কল করা হয়। Glance, ব্যাকগ্রাউন্ডে বিকল্প বান্ডেল আইটেম পড়ে, যাতে রানটাইম ডাইমেনশনের উপর ভিত্তি করে আপনার লেআউট নির্বিঘ্নে অ্যাডজাস্ট করা যায়।
  • onDeleted(Context, IntArray): ব্যবহারকারী কোনও নির্দিষ্ট উইজেট ইনস্ট্যান্স মুছে দিলে এটি চালু হয়।
  • onEnabled(Context): আপনার উইজেটের প্রথম ইনস্ট্যান্স সফলভাবে তৈরি হলে ট্রিগার করা হয়। গ্লোবাল মাইগ্রেশন চালানোর জন্য দারুণ।
  • onDisabled(Context): প্রোভাইডারের শেষ অ্যাক্টিভ ইনস্ট্যান্স সরিয়ে দেওয়া হলে কল করা হয়।
  • onReceive(Context, Intent): নির্দিষ্ট কলব্যাক পদ্ধতির আগে প্রতিটি প্ল্যাটফর্ম ব্রডকাস্ট ইন্টারসেপ্ট করে। আপনাকে নিশ্চিত করতে হবে যে আপনার লেখা যেকোনও কাস্টম রিসিভার লজিক super.onReceive(context, intent) কল করে এবং কখনও goAsync কল করবে না কারণ Glance অটোমেটিক অ্যাসিঙ্ক্রোনাসভাবে কাজ রুট করে।

উইজেট ব্রডকাস্ট ইনটেন্ট রিসিভ করা

ব্যাকগ্রাউন্ডে, GlanceAppWidgetReceiver নিম্নলিখিত ফাউন্ডেশনাল প্ল্যাটফর্ম উইজেট ব্রডকাস্ট ইনটেন্ট ফিল্টার ও ম্যানেজ করে:

UI তৈরি করুন

নিচে দেওয়া স্নিপেট থেকে বোঝা যাবে যে কীভাবে UI তৈরি করতে হয়:

/* 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
ছবি ১. একটি উদাহরণ UI।

কম্পোনেন্টের প্লেসমেন্ট ও সাইজ পরিবর্তন করতে, আপনি অ্যালাইনমেন্ট ভ্যালু পরিবর্তন করতে অথবা বিভিন্ন মডিফায়ার ভ্যালু (যেমন প্যাডিং) প্রয়োগ করতে পারবেন। প্রতিটি ক্লাসের জন্য কম্পোনেন্ট, প্যারামিটার ও উপলভ্য মডিফায়ারের সম্পূর্ণ তালিকা দেখতে রেফারেন্স ডকুমেন্টেশন দেখুন।

গোলাকার কোণ প্রয়োগ করুন

Android 12-এ সিস্টেম প্যারামিটার চালু করা হয়েছে যার মাধ্যমে আপনার অ্যাপ উইজেটের কর্নার রেডিয়াস ডায়নামিকভাবে কাস্টমাইজ করা যায়:

  • system_app_widget_background_radius: উইজেট ব্যাকগ্রাউন্ড কন্টেনারের কোণের ব্যাসার্ধ নির্দিষ্ট করে (কখনই ২৮ ডিপি-র বেশি নয়)।
  • ভিতরের ব্যাসার্ধ: কন্টেন্ট ক্লিপিং আটকাতে, সিস্টেম ব্যাকগ্রাউন্ড আউটলাইনের উপর ভিত্তি করে আপনার ভিতরের কন্টেন্টের জন্য একটি আনুপাতিক ব্যাসার্ধ গণনা করুন: systemRadiusValue - widgetPadding

Glance-এ, আপনি GlanceModifier.cornerRadius(android.R.dimen.system_app_widget_background_radius) ব্যবহার করে কম্পোজিশনে ডায়নামিকভাবে কর্নার রেডিয়াস সাইজিং প্রপার্টি প্রয়োগ করতে পারবেন।

Android 11 (API লেভেল ৩০) বা তার আগের ভার্সনে চলা ডিভাইসে ব্যাকওয়ার্ড কম্প্যাটিবিলিটির জন্য, কাস্টম অ্যাট্রিবিউট ও কাস্টম থিম রিসোর্স ফলব্যাক প্রয়োগ করুন:

  • /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>