تطبيقات مصغّرة للتطبيقات هي طرق عرض مصغّرة للتطبيقات يمكنك تضمينها في تطبيقات أخرى، مثل الشاشة الرئيسية، وتلقّي تحديثات دورية. يُشار إلى طرق العرض هذه باسم التطبيقات المصغّرة في واجهة المستخدم، ويمكنك نشر إحداها باستخدام موفّر تطبيق مصغّر (أو موفّر تطبيق مصغّر). يُطلق على مكوّن التطبيق الذي يتضمّن تطبيقات مصغّرة أخرى اسم مضيف التطبيق المصغّر (أو مضيف التطبيق المصغّر). يعرض الشكل 1 نموذجًا لأداة الموسيقى:

يوضّح هذا المستند كيفية نشر أداة باستخدام موفّر أدوات. للحصول على تفاصيل حول إنشاء AppWidgetHost
خاص بك لاستضافة تطبيقات مصغّرة، راجِع إنشاء مضيف للتطبيقات المصغّرة.
للحصول على معلومات حول كيفية تصميم التطبيق المصغّر، اطّلِع على نظرة عامة على تطبيقات الأجهزة.
مكوّنات التطبيق المصغّر
لإنشاء أداة، يجب توفُّر المكوّنات الأساسية التالية:
- عنصر
AppWidgetProviderInfo
- تصف هذه السمة البيانات الوصفية الخاصة بأداة، مثل تخطيط الأداة ومعدّل تكرار التحديث وفئة
AppWidgetProvider
.AppWidgetProviderInfo
محدَّد بتنسيق XML، كما هو موضَّح في هذا المستند. AppWidgetProvider
صف- تحدّد هذه السمة الطرق الأساسية التي تتيح لك التفاعل مع الأداة آليًا. من خلاله، تتلقّى عمليات بث عند تعديل الأداة أو تفعيلها أو إيقافها أو حذفها. عليك تعريف
AppWidgetProvider
في ملف البيان ثم تنفيذه، كما هو موضّح في هذا المستند. - عرض التنسيق
- تحدّد هذه السمة التخطيط الأوّلي للتطبيق المصغّر. يتم تحديد التصميم في XML، كما هو موضّح في هذا المستند.
يوضّح الشكل 2 كيف تتناسب هذه المكوّنات مع مسار المعالجة العام لتطبيقات الأجهزة المصغّرة.

إذا كان التطبيق المصغّر يتطلّب ضبطًا من المستخدم، عليك تنفيذ نشاط ضبط التطبيق المصغّر. يتيح هذا النشاط للمستخدمين تعديل إعدادات التطبيق المصغّر، مثل المنطقة الزمنية لتطبيق الساعة المصغّر.
- بدءًا من نظام التشغيل Android 12 (المستوى 31 من واجهة برمجة التطبيقات)، يمكنك توفير إعدادات تلقائية والسماح للمستخدمين بإعادة ضبط التطبيق المصغّر لاحقًا. لمزيد من التفاصيل، اطّلِع على استخدام الإعداد التلقائي للأداة والسماح للمستخدمين بإعادة ضبط الأدوات التي تم وضعها.
- في نظام التشغيل Android 11 (المستوى 30 لواجهة برمجة التطبيقات) أو الإصدارات الأقدم، يتم تشغيل هذا النشاط في كل مرة يضيف فيها المستخدم الأداة إلى شاشته الرئيسية.
ننصحك أيضًا بإجراء التحسينات التالية: تصاميم مرنة للأدوات وتحسينات متنوعة وأدوات متقدّمة وأدوات المجموعات وإنشاء مضيف للأدوات.
تعريف ملف AppWidgetProviderInfo XML
يحدّد الكائن AppWidgetProviderInfo
الصفات الأساسية للأداة.
حدِّد عنصر AppWidgetProviderInfo
في ملف مصدر XML باستخدام عنصر <appwidget-provider>
واحد واحفظه في مجلد res/xml/
الخاص بالمشروع.
يظهر ذلك في المثال التالي:
<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/example_loading_appwidget"
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" />
بدءًا من الإصدار 12 من نظام التشغيل Android:
استخدِم السمتَين targetCellWidth
وtargetCellHeight
كحجم تلقائي للأداة.
يبلغ حجم التطبيق المصغّر 2x2 تلقائيًا. يمكن تغيير حجم التطبيق المصغّر إلى 2x1 أو 4x3.
الإصدار 11 من نظام التشغيل Android والإصدارات الأقدم:
استخدِم السمتَين minWidth
وminHeight
لاحتساب المقاس التلقائي للأداة.
العرض التلقائي = Math.ceil(80 / 30)
= 3
الارتفاع التلقائي = Math.ceil(80 / 50)
= 2
يكون حجم التطبيق المصغّر 3x2 تلقائيًا. يمكن تغيير حجم التطبيق المصغّر إلى 2x1 أو ملء الشاشة.
سمات التطبيق المصغّر الإضافية
يوضّح الجدول التالي سمات <appwidget-provider>
المتعلقة بخصائص أخرى غير حجم الأداة.
السمات والوصف | |
---|---|
updatePeriodMillis |
تحدّد هذه السمة عدد المرات التي يطلب فيها إطار عمل التطبيق المصغّر إجراء تعديل من
AppWidgetProvider من خلال استدعاء طريقة معاودة الاتصال onUpdate() . لا نضمن أن يتم التحديث الفعلي في الوقت المحدد تمامًا باستخدام هذه القيمة، وننصحك بتعديلها بأقل قدر ممكن من التكرار، أي مرة واحدة في الساعة كحد أقصى، للحفاظ على شحن البطارية.
للاطّلاع على القائمة الكاملة للاعتبارات التي يجب أخذها في الحسبان عند اختيار فترة التحديث المناسبة، راجِع تحسينات لتعديل محتوى التطبيق المصغّر. |
initialLayout |
تشير هذه السمة إلى مورد التنسيق الذي يحدّد تنسيق الأداة. |
configure |
تحدّد هذه السمة النشاط الذي يتم تشغيله عندما يضيف المستخدم الأداة، ما يتيح له ضبط خصائص الأداة. راجِع مقالة السماح للمستخدمين بضبط التطبيقات المصغّرة. بدءًا من نظام التشغيل Android 12، يمكن لتطبيقك تخطّي عملية الإعداد الأولية. راجِع استخدام الإعداد التلقائي للأداة لمعرفة التفاصيل. |
description |
تحدّد هذه السمة وصف أداة اختيار التطبيقات المصغّرة الذي سيتم عرضه للأداة المصغّرة. تم طرح هذه الميزة في نظام التشغيل Android 12. |
previewLayout (الإصدار 12 من نظام التشغيل Android)
وpreviewImage (الإصدار 11 من نظام التشغيل Android والإصدارات الأقدم) |
previewImage
وpreviewLayout لكي يتمكّن تطبيقك من الرجوع إلى استخدام
previewImage إذا كان جهاز المستخدم لا يتوافق مع
previewLayout . لمزيد من التفاصيل، يُرجى الاطّلاع على
التوافق مع الإصدارات القديمة من معاينات التطبيقات المصغّرة القابلة لتغيير الحجم.
|
autoAdvanceViewId |
تحدّد هذه السمة معرّف العرض الخاص بالعرض الفرعي للتطبيق المصغّر الذي يتم تقديمه تلقائيًا من خلال مضيف التطبيق المصغّر. |
widgetCategory |
توضّح هذه السمة ما إذا كان يمكن عرض التطبيق المصغّر على الشاشة الرئيسية (home_screen ) أو شاشة القفل (keyguard ) أو كليهما. في الإصدار 5.0 من نظام التشغيل Android والإصدارات الأحدث، لا يكون الرمز home_screen صالحًا إلا للاستخدام.
|
widgetFeatures |
توضّح هذه السمة الميزات التي تتوافق مع الأداة. على سبيل المثال، إذا كنت تريد أن يستخدم تطبيقك المصغّر الإعدادات التلقائية عند إضافة مستخدم له، حدِّد العلامتَين configuration_optional وreconfigurable . يؤدي ذلك إلى تخطّي تشغيل نشاط الإعداد بعد أن يضيف المستخدم التطبيق المصغّر. وسيظل بإمكان المستخدم
إعادة ضبط إعدادات الأداة
بعد ذلك. |
استخدام فئة AppWidgetProvider للتعامل مع عمليات البث الخاصة بالتطبيقات المصغّرة
يتعامل صف AppWidgetProvider
مع عمليات بث التطبيقات المصغّرة ويعدّل التطبيق المصغّر
استجابةً لأحداث دورة حياة التطبيق المصغّر. توضّح الأقسام التالية كيفية تعريف AppWidgetProvider
في البيان ثم تنفيذه.
تعريف تطبيق مصغّر في البيان
أولاً، عرِّف الفئة AppWidgetProvider
في ملف AndroidManifest.xml
الخاص بتطبيقك، كما هو موضّح في المثال التالي:
<receiver android:name="ExampleAppWidgetProvider"
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/example_appwidget_info" />
</receiver>
يتطلّب العنصر <receiver>
السمة android:name
التي تحدّد AppWidgetProvider
المستخدَم من خلال الأداة. يجب عدم تصدير المكوّن إلا إذا كانت هناك عملية منفصلة تحتاج إلى البث إلى AppWidgetProvider
، وهو أمر غير شائع.
يجب أن يتضمّن العنصر <intent-filter>
عنصر <action>
مع السمة android:name
. تحدّد هذه السمة أنّ AppWidgetProvider
يقبل
ACTION_APPWIDGET_UPDATE
البث. وهذا هو البث الوحيد الذي يجب الإفصاح عنه بوضوح. يرسل
AppWidgetManager
تلقائيًا جميع عمليات بث الأدوات الأخرى إلى AppWidgetProvider
حسب الحاجة.
يحدّد العنصر <meta-data>
المرجع AppWidgetProviderInfo
ويتطلّب السمات التالية:
android:name
: تحدّد اسم البيانات الوصفية. استخدِمandroid.appwidget.provider
لتحديد البيانات كواصفAppWidgetProviderInfo
.android:resource
: تحدّد هذه السمة موقع المرجعAppWidgetProviderInfo
.
تنفيذ فئة AppWidgetProvider
توسّع الفئة AppWidgetProvider
BroadcastReceiver
كفئة
مريحة للتعامل مع عمليات بث الأدوات. ولا يتلقّى سوى عمليات البث للأحداث ذات الصلة بالأداة، مثل وقت تعديل الأداة أو حذفها أو تفعيلها أو إيقافها. عند حدوث أحداث البث هذه، يتم استدعاء الطرق التالية
AppWidgetProvider
:
onUpdate()
- يتم استدعاء هذه الدالة لتعديل التطبيق المصغّر على فترات زمنية محدّدة من خلال السمة
updatePeriodMillis
فيAppWidgetProviderInfo
. لمزيد من المعلومات، يُرجى الاطّلاع على الجدول الذي يصف سمات التطبيقات المصغّرة الإضافية في هذه الصفحة. - يتم استدعاء هذه الطريقة أيضًا عندما يضيف المستخدم التطبيق المصغّر، لذا فإنّها تنفّذ عملية الإعداد الأساسية، مثل تحديد معالجات الأحداث لعناصر
View
أو بدء المهام لتحميل البيانات لعرضها في التطبيق المصغّر. ومع ذلك، إذا أعلنت عن نشاط إعداد بدون العلامةconfiguration_optional
، لن يتم استدعاء هذه الطريقة عندما يضيف المستخدم التطبيق المصغّر، ولكن سيتم استدعاؤها عند إجراء التحديثات اللاحقة. ويقع على عاتق نشاط الإعداد إجراء التحديث الأول عند اكتمال عملية الإعداد. لمزيد من المعلومات، يُرجى الاطّلاع على السماح للمستخدمين بإعداد أدوات التطبيقات. - أهم دالة ردّ هي
onUpdate()
. يمكنك الاطّلاع على القسم التعامل مع الأحداث باستخدام فئةonUpdate()
في هذه الصفحة للحصول على مزيد من المعلومات. onAppWidgetOptionsChanged()
يتم استدعاء هذه الطريقة عند وضع التطبيق المصغّر لأول مرة وفي كل مرة يتم فيها تغيير حجمه. استخدِم دالة معاودة الاتصال هذه لعرض المحتوى أو إخفائه استنادًا إلى نطاقات أحجام الأداة. يمكنك الحصول على نطاقات الأحجام، وقائمة الأحجام المحتملة التي يمكن أن يتخذها مثيل تطبيق مصغّر بدءًا من Android 12، من خلال استدعاء
getAppWidgetOptions()
، الذي يعرضBundle
يتضمّن ما يلي:-
OPTION_APPWIDGET_MIN_WIDTH
: يحتوي على الحد الأدنى للعرض بوحدات dp لمثيل تطبيق مصغّر. -
OPTION_APPWIDGET_MIN_HEIGHT
: يحتوي على الحد الأدنى للارتفاع بوحدات dp لمثيل تطبيق مصغَّر. -
OPTION_APPWIDGET_MAX_WIDTH
: يحتوي على الحدّ الأعلى للعرض بوحدات dp لمثيل تطبيق مصغّر. -
OPTION_APPWIDGET_MAX_HEIGHT
: يحتوي على الحد الأعلى للارتفاع بوحدات dp لمثيل تطبيق مصغَّر. -
OPTION_APPWIDGET_SIZES
: تحتوي على قائمة بالمقاسات المحتملة (List<SizeF>
) بوحدات dp التي يمكن أن يتخذها مثيل أداة. تم طرح هذه الميزة في نظام التشغيل Android 12.
-
onDeleted(Context, int[])
يتم تنفيذ هذا الإجراء في كل مرة يتم فيها حذف تطبيق مصغّر من مضيف التطبيقات المصغّرة.
onEnabled(Context)
يتم استدعاء هذه الطريقة عند إنشاء مثيل للأداة لأول مرة. على سبيل المثال، إذا أضاف المستخدم نسختَين من تطبيقك المصغّر، لن يتم استدعاء هذه الدالة إلا في المرة الأولى. إذا كنت بحاجة إلى فتح قاعدة بيانات جديدة أو إجراء عملية إعداد أخرى لا تحتاج إلى تنفيذها إلا مرة واحدة لجميع مثيلات التطبيق المصغّر، فهذا هو المكان المناسب لتنفيذها.
onDisabled(Context)
يتم استدعاء هذا الإجراء عند حذف آخر مثيل للأداة من مضيف الأداة. هذا هو المكان الذي يمكنك فيه تنظيف أي عمل تم إجراؤه في
onEnabled(Context)
، مثل حذف قاعدة بيانات مؤقتة.onReceive(Context, Intent)
يتم استدعاء هذه الدالة لكل عملية بث وقبل كل طريقة من طرق معاودة الاتصال السابقة. لا تحتاج عادةً إلى تنفيذ هذه الطريقة، لأنّ التنفيذ التلقائي
AppWidgetProvider
يفلتر جميع عمليات بث التطبيقات المصغّرة ويستدعي الطرق السابقة حسب الاقتضاء.
يجب تعريف تنفيذ فئة AppWidgetProvider
على أنّه أداة استقبال بث باستخدام العنصر <receiver>
في AndroidManifest
. يمكنك الاطّلاع على قسم تعريف أداة في ملف البيان في هذه الصفحة للحصول على مزيد من المعلومات.
التعامل مع الأحداث باستخدام فئة onUpdate()
أهم دالة AppWidgetProvider
ردّ نداء هي onUpdate()
، لأنّه يتم استدعاؤها عند إضافة كل أداة إلى مضيف، ما لم تستخدم نشاط إعداد بدون العلامة configuration_optional
. إذا كانت الأداة تقبل أي أحداث تفاعل من المستخدم، سجِّل معالجات الأحداث في دالة معاودة الاتصال هذه. إذا كان تطبيقك المصغّر لا ينشئ ملفات أو قواعد بيانات مؤقتة، أو لا ينفّذ أي مهام أخرى تتطلّب التنظيف، قد تكون onUpdate()
هي طريقة معاودة الاتصال الوحيدة التي تحتاج إلى تحديدها.
على سبيل المثال، إذا كنت تريد تطبيقًا مصغّرًا يتضمّن زرًا يطلق نشاطًا عند النقر عليه، يمكنك استخدام التنفيذ التالي لـ AppWidgetProvider
:
Kotlin
class ExampleAppWidgetProvider : AppWidgetProvider() { override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // Perform this loop procedure for each widget that belongs to this // provider. appWidgetIds.forEach { appWidgetId -> // Create an Intent to launch ExampleActivity. val pendingIntent: PendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ Intent(context, ExampleActivity::class.java), /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // Get the layout for the widget and attach an onClick listener to // the button. val views: RemoteViews = RemoteViews( context.packageName, R.layout.appwidget_provider_layout ).apply { setOnClickPendingIntent(R.id.button, pendingIntent) } // Tell the AppWidgetManager to perform an update on the current // widget. appWidgetManager.updateAppWidget(appWidgetId, views) } } }
Java
public class ExampleAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // Perform this loop procedure for each widget that belongs to this // provider. for (int i=0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; // Create an Intent to launch ExampleActivity Intent intent = new Intent(context, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ intent, /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); // Get the layout for the widget and attach an onClick listener to // the button. RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout); views.setOnClickPendingIntent(R.id.button, pendingIntent); // Tell the AppWidgetManager to perform an update on the current app // widget. appWidgetManager.updateAppWidget(appWidgetId, views); } } }
لا يحدّد AppWidgetProvider
هذا سوى طريقة onUpdate()
، ويستخدمها لإنشاء PendingIntent
الذي يشغّل Activity
ويربطه بزر الأداة باستخدام setOnClickPendingIntent(int,
PendingIntent)
. يتضمّن هذا الرمز حلقة تتكرّر خلال كل إدخال في appWidgetIds
، وهو عبارة عن مصفوفة من أرقام التعريف التي تحدّد كل أداة تم إنشاؤها بواسطة مقدّم الخدمة هذا. إذا أنشأ المستخدم أكثر من نسخة واحدة من التطبيق المصغّر، سيتم تعديلها كلها في الوقت نفسه. ومع ذلك، تتم إدارة updatePeriodMillis
جدول
واحد فقط لجميع مثيلات الأداة. على سبيل المثال، إذا تم تحديد جدول التحديث ليكون كل ساعتين، وتمت إضافة نسخة ثانية من التطبيق المصغّر بعد ساعة واحدة من النسخة الأولى، سيتم تحديثهما معًا خلال الفترة المحددة في النسخة الأولى، وسيتم تجاهل فترة التحديث الثانية. ويتم تعديل كليهما كل ساعتين، وليس كل ساعة.
يمكنك الاطّلاع على
ExampleAppWidgetProvider.java
للحصول على مزيد من التفاصيل.
تلقّي أغراض بث التطبيقات المصغّرة
AppWidgetProvider
هي فئة مناسبة. إذا كنت تريد تلقّي عمليات البث الخاصة بالأداة مباشرةً، يمكنك تنفيذ BroadcastReceiver
أو إلغاء onReceive(Context,Intent)
. في ما يلي النوايا التي يجب الاهتمام بها:
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
إنشاء تخطيط الأداة
يجب تحديد تصميم أولي للأداة في XML وحفظه في دليل res/layout/
الخاص بالمشروع. يمكنك الرجوع إلى إرشادات التصميم للاطّلاع على التفاصيل.
إنشاء تخطيط الأداة بسيط إذا كنت على دراية بالتخطيطات. يُرجى العِلم أنّ تصاميم التطبيقات المصغّرة تستند إلى RemoteViews
،
الذي لا يتوافق مع كل أنواع التصاميم أو التطبيقات المصغّرة للعرض. لا يمكنك استخدام طرق عرض مخصّصة أو فئات فرعية من طرق العرض المتوافقة مع RemoteViews
.
تتيح السمة RemoteViews
أيضًا استخدام ViewStub
،
وهي View
غير مرئية وبحجم صفر يمكنك استخدامها لتوسيع موارد التنسيق
بشكل غير متزامن في وقت التشغيل.
التوافق مع السلوك ذي الحالة
يضيف نظام التشغيل Android 12 إمكانية استخدام السلوك المرتبط بالحالة من خلال المكوّنات الحالية التالية:
لا يزال التطبيق المصغّر بلا حالة. يجب أن يخزِّن تطبيقك الحالة وأن يسجّل أحداث تغيير الحالة.

يوضّح مثال الرمز التالي كيفية تنفيذ هذه المكوّنات.
Kotlin
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true) // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2) // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent) )
Java
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true); // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2); // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));
قدِّم تصميمَين: أحدهما يستهدف الأجهزة التي تعمل بالإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث في res/layout-v31
، والآخر يستهدف الإصدار 11 من نظام التشغيل Android أو الإصدارات الأقدم في المجلد التلقائي res/layout
.
تنفيذ زوايا دائرية
يقدّم نظام التشغيل Android 12 مَعلمات النظام التالية لضبط أنصاف أقطار الزوايا المنحنية في تطبيقك المصغّر:
system_app_widget_background_radius
: تمثّل هذه السمة نصف قطر زاوية خلفية التطبيق المصغّر، ولا يمكن أن تتجاوز قيمتها 28 dp.نصف القطر الداخلي، ويمكن حسابه من نصف القطر الخارجي والهامش. راجِع المقتطف التالي:
/** * Applies corner radius for views that are visually positioned [widgetPadding]dp inside of the * widget background. */ @Composable fun GlanceModifier.appWidgetInnerCornerRadius(widgetPadding: Dp): GlanceModifier { if (Build.VERSION.SDK_INT < 31) { return this } val resources = LocalContext.current.resources // get dimension in float (without rounding). val px = resources.getDimension(android.R.dimen.system_app_widget_background_radius) val widgetBackgroundRadiusDpValue = px / resources.displayMetrics.density if (widgetBackgroundRadiusDpValue < widgetPadding.value) { return this } return this.cornerRadius(Dp(widgetBackgroundRadiusDpValue - widgetPadding.value)) }
لاحتساب نصف قطر مناسب للمحتوى الداخلي للأداة، استخدِم الصيغة التالية: systemRadiusValue - widgetPadding
يجب أن تستخدم التطبيقات المصغّرة التي تقص محتواها إلى أشكال غير مستطيلة
@android:id/background
كمعرّف عرض لعرض الخلفية الذي تم ضبط
android:clipToOutline
على true
.
اعتبارات مهمة بشأن الزوايا الدائرية
- يمكن لمشغّلات التطبيقات التابعة لجهات خارجية والشركات المصنّعة للأجهزة تجاهل المَعلمة
system_app_widget_background_radius
ليكون حجمها أقل من 28 dp. إذا كانت الأداة لا تستخدم
@android:id/background
أو لم تحدّد خلفية تقتطع محتواها استنادًا إلى المخطط التفصيلي، مع ضبطandroid:clipToOutline
علىtrue
، سيحدّد مشغّل التطبيقات الخلفية تلقائيًا ويقتطع الأداة باستخدام مستطيل ذي زوايا مستديرة تم ضبط نصف قطرها على نصف القطر التلقائي.يجب أن تكون الأشكال غير المستطيلة مضمّنة في حاوية تغيير الحجم المستطيلة الدائرية الخاصة بها حتى لا يتم اقتصاصها.
اعتبارًا من Android 16، ستكون قيمة نظام AOSP الخاصة بـ
system_app_widget_background_radius
هي24dp
. قد تقصّ مشغّلات التطبيقات والشركات المصنّعة للأجهزة التطبيق المصغّر إلىsystem_app_widget_background_radius
.يجب أن يحتوي المحتوى الداخلي للأداة على مساحة كافية لتوفير قيم نصف القطر حتى
28dp
لتجنُّب اقتصاص المحتوى بسبب الزوايا الدائرية.system_app_widget_background_radius
لضمان توافق التطبيق المصغّر مع الإصدارات السابقة من Android، ننصحك بتحديد سمات مخصّصة واستخدام مظهر مخصّص لتجاوزها في Android 12، كما هو موضّح في ملفات XML النموذجية التالية:
/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>
/layout/my_widget_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:background="@drawable/my_widget_background" />