توضّح الأقسام التالية كيفية إنشاء أداة تطبيق أساسية باستخدام Glance.
تعريف AppWidget في ملف البيان
بعد إكمال خطوات الإعداد، عليك الإفصاح عن AppWidget وبياناته الوصفية في تطبيقك.
تمديد جهاز الاستقبال
AppWidgetمنGlanceAppWidgetReceiver:class MyAppWidgetReceiver : GlanceAppWidgetReceiver() { override val glanceAppWidget: GlanceAppWidget = TODO("Create GlanceAppWidget") }
سجِّل موفِّر أداة التطبيق في ملف
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 السمات الأساسية للأداة. حدِّد 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 (الإصدار 12 من نظام التشغيل Android) وminWidth وminHeight |
targetCellWidth وtargetCellHeight، وminWidth وminHeight،
حتى يتمكّن تطبيقك من الرجوع إلى استخدام
minWidth وminHeight إذا كان جهاز المستخدم
لا يتوافق مع targetCellWidth وtargetCellHeight. في حال توفّرها، تحظى السمتان 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 بكسل غير مرتبط بالكثافة وطولها 50 بكسل غير مرتبط بالكثافة.
- يتم توفير مواصفات السمة التالية:
<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.
الإصدار 11 من نظام التشغيل Android والإصدارات الأقدم:
استخدِم السمتَين 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 (الإصدار 12 من نظام التشغيل Android)
وpreviewImage (الإصدار 11 من نظام التشغيل Android والإصدارات الأقدم) |
|
autoAdvanceViewId |
تحدّد هذه السمة معرّف العرض الفرعي للتطبيق المصغّر الذي يتم تقديمه تلقائيًا من خلال مضيف التطبيق المصغّر. |
widgetCategory |
توضّح هذه السمة ما إذا كان يمكن عرض التطبيق المصغّر على الشاشة الرئيسية (home_screen) أو شاشة القفل (keyguard) أو كليهما. في الإصدار 5.0 من نظام التشغيل Android والإصدارات الأحدث، لا يكون الرمز home_screen صالحًا إلا. |
widgetFeatures |
توضّح هذه السمة الميزات التي تتيحها الأداة. على سبيل المثال، إذا كان ضبط إعدادات التطبيق المصغّر اختياريًا، حدِّد كلاً من configuration_optional وreconfigurable. |
تعريف GlanceAppWidget
أنشئ فئة جديدة تتضمّن
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") } } }
أنشئ مثيلاً له في
glanceAppWidgetعلى جهازGlanceAppWidgetReceiver:class MyAppWidgetReceiver : GlanceAppWidgetReceiver() { // Let MyAppWidgetReceiver know which GlanceAppWidget to use override val glanceAppWidget: GlanceAppWidget = MyAppWidget() }
لقد أعددت الآن AppWidget باستخدام Glance.
استخدام فئة GlanceAppWidgetReceiver للتعامل مع عمليات البث الخاصة بالتطبيق المصغّر
تبث أداة GlanceAppWidgetReceiver الإحداثيات وتعدّل حالة النظام الأساسي من خلال توسيع نطاق AppWidgetProvider الأساسي. يتلقّى هذا التطبيق أحداثًا من النظام الأساسي عند تعديل التطبيق المصغّر أو حذفه أو تفعيله أو إيقافه، ويحوّلها إلى طلبات دورة حياة Compose.
تعريف تطبيق مصغّر في البيان
عليك تعريف الفئة الفرعية للفئة 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 الوصفية الخاص بـ AppWidgetProviderInfo (@xml/my_app_widget_info).
تنفيذ فئة GlanceAppWidgetReceiver
في Glance، يمكنك توسيع GlanceAppWidgetReceiver بدلاً من AppWidgetProvider مباشرةً. يمكنك تنفيذ ذلك من خلال ربط جهاز الاستقبال بنسخة GlanceAppWidget. تعمل عمليات الرجوع الأساسية المتوفّرة في
GlanceAppWidgetReceiver على النحو التالي:
-
onUpdate(): يتم تجاهله تلقائيًا من خلال Glance لتنفيذ تحديثات التركيب. في حال تجاهلonUpdateيدويًا، يجب استدعاءsuper.onUpdateللسماح لـ Glance بتشغيل سلاسل الإنشاء بنجاح. -
onAppWidgetOptionsChanged(): يتم استدعاؤها عند وضع التطبيق المصغّر للمرة الأولى أو عند تغيير حجمه. تجمع خيارات القراءة السريعة العناصر في الخلفية، ما يتيح تعديل التصميم بسلاسة استنادًا إلى أبعاد وقت التشغيل. -
onDeleted(Context, IntArray): يتم استدعاؤه عندما يحذف المستخدم مثيلاً معيّنًا من أداة. -
onEnabled(Context): يتم تفعيل هذا الحدث عند إنشاء أول مثيل للأداة بنجاح. وهي ممتازة لتنفيذ عمليات نقل البيانات على مستوى العالم. -
onDisabled(Context): يتم استدعاؤه عند إزالة آخر مثيل نشط للموفّر. -
onReceive(Context, Intent): يعترض كل عملية بث على المنصة قبل تنفيذ طرق معاودة الاتصال المحدّدة. يجب التأكّد من أنّ أي منطق مخصّص لجهاز الاستقبال تكتبه يستدعيsuper.onReceive(context, intent)، ويجب ألا يستدعيgoAsyncبنفسك لأنّ Glance يوجّه العمل تلقائيًا بشكل غير متزامن.
تلقّي أغراض البث الخاصة بالتطبيقات المصغّرة
في الخلفية، تعمل GlanceAppWidgetReceiver على فلترة ومعالجة ما يلي
من أغراض البث الأساسية الخاصة بأداة المنصة:
ACTION_APPWIDGET_UPDATEACTION_APPWIDGET_DELETEDACTION_APPWIDGET_ENABLEDACTION_APPWIDGET_DISABLEDACTION_APPWIDGET_OPTIONS_CHANGED
Create 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باستخدام تعبير lambda. الترتيب مهم.
يمكنك تغيير قيم المحاذاة أو تطبيق قيم معدِّلات مختلفة (مثل padding) لتغيير موضع المكوّنات وحجمها. راجِع مستندات المرجع للحصول على قائمة كاملة بالمكوّنات والمَعلمات والمعدّلات المتاحة لكل فئة.
تنفيذ الزوايا الدائرية
يقدّم نظام التشغيل Android 12 مَعلمات نظام لتخصيص أنصاف أقطار الزوايا لتطبيقاتك المصغّرة بشكل ديناميكي:
system_app_widget_background_radius: تحدّد هذه السمة نصف قطر زاوية حاوية خلفية التطبيق المصغّر (يجب ألا يتجاوز 28 وحدة بكسل مستقلة الكثافة).- نصف القطر الداخلي: لمنع قص المحتوى، احسب نصف قطر متناسبًا للمحتوى الداخلي استنادًا إلى المخطط التفصيلي لخلفية النظام:
systemRadiusValue - widgetPadding
في Glance، يمكنك تطبيق خصائص تحديد حجم نصف قطر الزاوية بشكل ديناميكي في التركيب باستخدام GlanceModifier.cornerRadius(android.R.dimen.system_app_widget_background_radius).
لضمان التوافق مع الأنظمة القديمة على الأجهزة التي تعمل بالإصدار 11 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 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>