ایجاد ابزاره برنامه با Glance

بخش‌های زیر نحوه ایجاد ابزاره برنامه پایه با Glance را شرح می‌دهد.

‫AppWidget را در «مانیفست» اعلام کنید

پس‌از تکمیل مراحل راه‌اندازی، AppWidget و فراداده‌های آن را در برنامه‌تان اعلام کنید.

  1. گیرنده AppWidget را از GlanceAppWidgetReceiver گسترش دهید:

    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>

اعلام کردن XML مربوط به AppWidgetProviderInfo

شیء AppWidgetProviderInfo کیفیت‌های ضروری ابزارک شما را تعریف می‌کند. AppWidgetProviderInfo را در فایل منبع فراداده XML خود (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 استفاده کنید.

مثال

برای نشان دادن اینکه چگونه مشخصه‌های جدول قبلی بر اندازه ابزارک تأثیر می‌گذارند، مشخصات زیر را درنظر بگیرید:

  • سلول شبکه ۳۰ دی‌پی عرض و ۵۰ دی‌پی ارتفاع دارد.
  • مشخصات مشخصه زیر ارائه شده است:
<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۱ کوچک کنید یا تا ۴x۳ بزرگ کنید.

Android 11 و نسخه‌های پایین‌تر:

از مشخصه‌های minWidth و minHeight برای محاسبه اندازه پیش‌فرض ابزارک استفاده کنید.

عرض پیش‌فرض = Math.ceil(80 / 30) = ۳

ارتفاع پیش‌فرض = Math.ceil(80 / 50) = ۲

اندازه پیش‌فرض ابزارک ۳x۲ است. اندازه این ابزارک را می‌توانید تا ۲×۱ کوچک کنید یا تا تمام‌صفحه بزرگ کنید.

مشخصه‌های اضافی ابزاره

جدول زیر <appwidget-provider> مشخصه مربوط به کیفیت‌های دیگر به‌جز اندازه ابزارک را شرح می‌دهد.

مشخصه‌ها و شرح
updatePeriodMillis تعریف می‌کند چارچوب ابزاره هرچندوقت یک‌بار با فراخوانی روش onUpdate() بازخوان GlanceAppWidgetReceiver درخواست به‌روزرسانی می‌کند. توصیه می‌کنیم تا حد امکان به‌روزرسانی را به‌ندرت انجام دهید—حداکثر یک بار در ساعت—تا در مصرف باتری صرفه‌جویی شود. برای جزئیات، بخش چه زمانی ابزارک‌ها را به‌روزرسانی کنیم در مدیریت وضعیت «نگاه سریع» را ببینید.
initialLayout به منبع چیدمانی اشاره می‌کند که چیدمان بار کردن ابزاره را قبل‌از پرداز کردن ترکیب‌های «واسط کاربر Glance» تعریف می‌کند. می‌توانید از چیدمان بارگیری ازپیش‌تعریف‌شده‌ای که در کتابخانه ارائه شده است استفاده کنید: @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 نسخه ۵.۰ و بالاتر، فقط 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. آن را در glanceAppWidget در GlanceAppWidgetReceiver خود نمونه‌سازی کنید:

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

اکنون AppWidget را بااستفاده از Glance پیکربندی کرده‌اید.

از کلاس GlanceAppWidgetReceiver برای مدیریت همه‌فرستی‌های ابزارک استفاده کنید

ابزارک مختصات GlanceAppWidgetReceiver وضعیت پلاتفرم و به‌روزرسانی‌ها را با گسترش AppWidgetProvider زیرین همه‌فرستی می‌کند. وقتی ابزارک شما به‌روزرسانی، حذف، فعال، یا غیرفعال می‌شود، رویدادهای پلاتفرم را دریافت می‌کند و آن‌ها را به درخواست‌های چرخه حیات «نوشتن» ترجمه می‌کند.

ابزاره‌ای را در مانیفست اعلام کنید

زیرکلاس کلاس GlanceAppWidgetReceiver را به‌عنوان گیرنده همه‌فرستی در فایل AndroidManifest.xml خود اعلام کنید:

<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 نیاز دارد که کلاس گیرنده را مشخص می‌کند. گیرنده باید کنش همه‌فرستی ACTION_APPWIDGET_UPDATE را در <intent-filter> بپذیرد.

عنصر <meta-data> باید نام خود را به‌عنوان android.appwidget.provider شناسایی کند و مشخصه android:resource باید به فراداده منبع XML «اطلاعات ارائه‌دهنده ابزارک برنامه» شما (@xml/my_app_widget_info) اشاره کند.

پیاده‌سازی کلاس GlanceAppWidgetReceiver

در «نگاه سریع»، به‌جای AppWidgetProvider مستقیماً، GlanceAppWidgetReceiver را گسترش می‌دهید. با پیوند دادن گیرنده به نمونه GlanceAppWidget آن را پیاده‌سازی کنید. عملکرد تماس‌های برگشتی اصلی دردسترس در GlanceAppWidgetReceiver به این صورت است:

  • onUpdate(): «نگاه سریع» به‌طور خودکار آن را ملغی می‌کند تا به‌روزرسانی‌های ترکیب را اجرا کند. اگر به‌صورت دستی onUpdate را ملغی کنید، باید با super.onUpdate تماس بگیرید تا به «نگاه سریع» اجازه دهید رشته‌های نگارش را با موفقیت راه‌اندازی کند.
  • onAppWidgetOptionsChanged(): زمانی که ابزاره برای اولین‌بار قرار داده می‌شود یا تغییر اندازه می‌دهد، فراخوانده می‌شود. «نگاه سریع» موارد دسته‌ای گزینه‌ها را در زیر کاپوت می‌خواند تا چیدمان شما براساس ابعاد زمان اجرا به‌طور یکپارچه تنظیم شود.
  • 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). نمایش نهایی به فضای موجود بستگی دارد. تصویر زیر نمونه‌ای از ظاهر احتمالی آن است:
ابزارک_مقصد
شکل ۱. میانای کاربر نمونه.

می‌توانید مقادیر تراز را تغییر دهید یا مقادیر اصلاح‌گر متفاوتی (مثل حاشیه) را اعمال کنید تا جای و اندازه عناصر را تغییر دهید. برای فهرست کامل عناصر، پارامترها، و اصلاح‌کننده‌های دردسترس برای هر کلاس، اسناد مرجع را ببینید.

پیاده‌سازی گوشه‌های گرد

‫Android 12 پارامترهای سیستمی را برای سفارشی‌سازی کردن شعاع گوشه‌های ابزاره‌های برنامه به‌صورت پویا معرفی می‌کند:

  • system_app_widget_background_radius: شعاع گوشه محتوی پس‌زمینه ابزاره را مشخص می‌کند (هرگز بزرگ‌تر از ۲۸ پیکسل نیست).
  • شعاع داخلی: برای جلوگیری از برش محتوا، شعاع متناسبی برای محتوای داخلی خود براساس خطوط کلی پس‌زمینه سیستم محاسبه کنید: systemRadiusValue - widgetPadding

در «نگاهی گذرا»، می‌توانید ویژگی‌های اندازه شعاع گوشه را به‌صورت پویا در ترکیب بااستفاده از GlanceModifier.cornerRadius(android.R.dimen.system_app_widget_background_radius) اعمال کنید.

برای سازگاری با نسخه‌های قدیمی در دستگاه‌های دارای Android 11 (میانای برنامه کاربردی سطح ۳۰) یا پایین‌تر، ویژگی‌های سفارشی و منابع جایگزین زمینه سفارشی را پیاده‌سازی کنید:

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