تطبيقات مصغّرة للتطبيقات هي طرق عرض مصغّرة للتطبيقات يمكنك تضمينها في تطبيقات أخرى، مثل الشاشة الرئيسية، وتلقّي تحديثات دورية. يُشار إلى طرق العرض هذه باسم التطبيقات المصغّرة في واجهة المستخدم، ويمكنك نشر إحداها باستخدام موفّر تطبيقات مصغّرة (أو موفّر تطبيقات مصغّرة). يُطلق على مكوّن التطبيق الذي يتضمّن تطبيقات مصغّرة أخرى اسم مضيف التطبيق المصغّر (أو مضيف التطبيق المصغّر). يعرض الشكل 1 عيّنة من أداة الموسيقى:
يوضّح هذا المستند كيفية نشر أداة باستخدام موفّر أدوات. للحصول على تفاصيل حول إنشاء AppWidgetHost خاص بك لاستضافة تطبيقات مصغّرة، راجِع إنشاء مضيف للتطبيقات المصغّرة.
للحصول على معلومات حول كيفية تصميم التطبيق المصغّر، اطّلِع على نظرة عامة على تطبيقات الأجهزة.
مكوّنات التطبيق المصغّر
لإنشاء أداة، يجب توفُّر المكوّنات الأساسية التالية:
- عنصر
AppWidgetProviderInfo - تصف هذه السمة البيانات الوصفية الخاصة بأداة، مثل تخطيط الأداة ومعدّل تكرار التحديث وفئة
AppWidgetProvider.AppWidgetProviderInfoمحدَّد بتنسيق XML، كما هو موضَّح في هذا المستند. AppWidgetProviderصف- تحدّد هذه السمة الطرق الأساسية التي تتيح لك التفاعل مع الأداة آليًا. من خلاله، تتلقّى عمليات بث عند تعديل الأداة أو تفعيلها أو إيقافها أو حذفها. عليك تعريف
AppWidgetProviderفي ملف البيان ثم تنفيذه، كما هو موضّح في هذا المستند. - تنسيق العرض
- تحدّد هذه السمة التنسيق الأوّلي للتطبيق المصغّر. يتم تحديد التصميم في XML، كما هو موضّح في هذا المستند.
يوضّح الشكل 2 كيفية ملاءمة هذه المكوّنات في مسار المعالجة العام لأداة التطبيق.
إذا كان التطبيق المصغّر يتطلّب ضبطًا من المستخدم، عليك تنفيذ نشاط ضبط التطبيق المصغّر. يتيح هذا النشاط للمستخدمين تعديل إعدادات التطبيق المصغّر، مثل المنطقة الزمنية لتطبيق الساعة المصغّر.
- بدءًا من نظام التشغيل Android 12 (المستوى 31 من واجهة برمجة التطبيقات)، يمكنك تقديم إعدادات تلقائية والسماح للمستخدمين بإعادة ضبط التطبيق المصغّر لاحقًا. لمزيد من التفاصيل، اطّلِع على استخدام الإعداد التلقائي للأداة والسماح للمستخدمين بإعادة ضبط الأدوات التي تم وضعها.
- في الإصدار 11 من نظام التشغيل Android (المستوى 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 (Android 12)
و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_UPDATEACTION_APPWIDGET_DELETEDACTION_APPWIDGET_ENABLEDACTION_APPWIDGET_DISABLEDACTION_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 وحدة بكسل مستقلة الكثافة.نصف القطر الداخلي، ويمكن حسابه من نصف القطر الخارجي والمسافة المتروكة. راجِع المقتطف التالي:
/** * 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" />