توفير تنسيقات مرنة للتطبيقات المصغّرة

تجربة طريقة Compose
‫Jetpack Compose هي مجموعة أدوات واجهة المستخدم المقترَحة لنظام التشغيل Android. تعرَّف على كيفية إنشاء التطبيقات المصغّرة باستخدام واجهات برمجة تطبيقات Compose-style.

توضّح هذه الصفحة التحسينات التي تم إجراؤها على حجم التطبيقات المصغّرة والمرونة الأكبر التي تم تقديمها في Android 12 (مستوى واجهة برمجة التطبيقات 31). وتوضّح أيضًا كيفية تحديد حجم التطبيق المصغّر.

استخدام واجهات برمجة التطبيقات المحسّنة لأحجام التطبيقات المصغّرة وتنسيقاتها

بدءًا من الإصدار 12 من نظام التشغيل Android (المستوى 31 لواجهة برمجة التطبيقات)، يمكنك توفير سمات حجم أكثر دقة وتنسيقات مرنة من خلال تنفيذ ما يلي، كما هو موضّح في الأقسام التالية:

  1. تحديد قيود إضافية على حجم التطبيق المصغّر

  2. توفير تنسيقات متجاوبة أو تنسيقات دقيقة

في الإصدارات السابقة من Android، يمكن الحصول على نطاقات حجم التطبيق المصغّر باستخدام الإضافات OPTION_APPWIDGET_MIN_WIDTH وOPTION_APPWIDGET_MIN_HEIGHT وOPTION_APPWIDGET_MAX_WIDTH وOPTION_APPWIDGET_MAX_HEIGHT، ثم تقدير حجم التطبيق المصغّر، ولكن هذا المنطق لا يعمل في جميع الحالات. بالنسبة إلى التطبيقات المصغّرة التي تستهدف الإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث، ننصحك بتوفير تصاميم متجاوبة أو دقيقة.

تحديد قيود إضافية على حجم التطبيق المصغّر

يضيف Android 12 واجهات برمجة تطبيقات تتيح لك التأكّد من أنّ حجم التطبيق المصغّر مناسب على مختلف الأجهزة ذات أحجام الشاشات المتفاوتة.

بالإضافة إلى السمات الحالية minWidth وminHeight وminResizeWidth وminResizeHeight، استخدِم سمات appwidget-provider الجديدة التالية:

  • targetCellWidth وtargetCellHeight: تحدِّد الحجم المستهدَف للأداة من حيث خلايا شبكة مشغّل التطبيقات. في حال تحديد هذه السمات، يتم استخدامها بدلاً من minWidth أو minHeight.

  • maxResizeWidth وmaxResizeHeight: تحدِّدان الحد الأقصى للحجم الذي يسمح به مشغّل التطبيقات للمستخدم بتغيير حجم التطبيق المصغّر إليه.

يوضّح ملف XML التالي كيفية استخدام سمات تحديد الحجم.

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  android:targetCellWidth="3"
  android:targetCellHeight="2"
  android:maxResizeWidth="250dp"
  android:maxResizeHeight="110dp">
</appwidget-provider>

توفير تنسيقات سريعة الاستجابة

إذا كان التنسيق يحتاج إلى التغيير حسب حجم التطبيق المصغّر، ننصحك بإنشاء مجموعة صغيرة من التنسيقات، كل منها صالح لمجموعة من الأحجام. إذا لم يكن ذلك ممكنًا، يمكنك تقديم تنسيقات استنادًا إلى الحجم الدقيق للتطبيق المصغّر في وقت التشغيل، كما هو موضّح في هذه الصفحة.

تتيح هذه الميزة تغيير الحجم بسلاسة وتحسين أداء النظام بشكل عام، لأنّ النظام لا يحتاج إلى تنشيط التطبيق في كل مرة يعرض فيها التطبيق المصغّر بحجم مختلف.

يوضّح مثال الرمز البرمجي التالي كيفية تقديم قائمة بالتنسيقات.

override fun onUpdate(
    /* ... */
) {
    val smallView = RemoteViews(
        /* ... */
    )
    val tallView = RemoteViews(
        /* ... */
    )
    val wideView = RemoteViews(
        /* ... */
    )

    val viewMapping: Map<SizeF, RemoteViews> = mapOf(
        SizeF(150f, 100f) to smallView,
        SizeF(150f, 200f) to tallView,
        SizeF(215f, 100f) to wideView
    )
    val remoteViews = RemoteViews(viewMapping)

    appWidgetManager.updateAppWidget(id, remoteViews)
}

لنفترض أنّ التطبيق المصغّر يتضمّن السمات التالية:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minResizeWidth="160dp"
    android:minResizeHeight="110dp"
    android:maxResizeWidth="250dp"
    android:maxResizeHeight="200dp">
</appwidget-provider>

يعني مقتطف الرمز السابق ما يلي:

  • يتيح smallView استخدام أحجام من 160 بكسل مستقل الكثافة (minResizeWidth) × 110 بكسل مستقل الكثافة (minResizeHeight) إلى 160 بكسل مستقل الكثافة × 199 بكسل مستقل الكثافة (نقطة القطع التالية - 1 بكسل مستقل الكثافة).
  • يتيح tallView استخدام أحجام من 160 بكسل مستقل الكثافة × 200 بكسل مستقل الكثافة إلى 214 بكسل مستقل الكثافة (نقطة القطع التالية - 1) × 200 بكسل مستقل الكثافة.
  • يتيح wideView استخدام أحجام من 215 بكسل مستقل الكثافة × 110 بكسل مستقل الكثافة (minResizeHeight) إلى 250 بكسل مستقل الكثافة (maxResizeWidth) × 200 بكسل مستقل الكثافة (maxResizeHeight).

يجب أن يتوافق تطبيقك المصغّر مع نطاق الحجم من minResizeWidth × minResizeHeight إلى maxResizeWidth × maxResizeHeight. ضمن هذا النطاق، يمكنك تحديد نقطة القطع لتبديل التخطيطات.

مثال على التخطيط سريع الاستجابة
الشكل 1: مثال على تصميم متجاوب

تقديم تخطيطات دقيقة

إذا لم تكن مجموعة صغيرة من التنسيقات المتجاوبة ممكنة، يمكنك بدلاً من ذلك تقديم تنسيقات مختلفة مخصّصة للأحجام التي يتم عرض التطبيق المصغّر بها. ويكون ذلك عادةً بحجمَين للهواتف (الوضع العمودي والوضع الأفقي) وأربعة أحجام للأجهزة القابلة للطي.

لتنفيذ هذا الحلّ، يجب أن يتّبع تطبيقك الخطوات التالية:

  1. استخدِم الدالة AppWidgetProvider.onAppWidgetOptionsChanged() التي يتم استدعاؤها عند تغيير مجموعة الأحجام.

  2. استدعِ AppWidgetManager.getAppWidgetOptions()، التي تعرض Bundle يحتوي على الأحجام.

  3. الوصول إلى مفتاح AppWidgetManager.OPTION_APPWIDGET_SIZES من Bundle

يوضّح مثال الرمز التالي كيفية تقديم تنسيقات دقيقة.

override fun onAppWidgetOptionsChanged(
    context: Context,
    appWidgetManager: AppWidgetManager,
    id: Int,
    newOptions: Bundle?
) {
    super.onAppWidgetOptionsChanged(context, appWidgetManager, id, newOptions)
    // Get the new sizes.
    val sizes = newOptions?.let {
        BundleCompat.getParcelableArrayList(
            it,
            AppWidgetManager.OPTION_APPWIDGET_SIZES,
            SizeF::class.java
        )
    }
    // Check that the list of sizes is provided by the launcher.
    if (sizes.isNullOrEmpty()) {
        return
    }
    // Map the sizes to the RemoteViews that you want.
    val remoteViews = RemoteViews(sizes.associateWith(::createRemoteViews))
    appWidgetManager.updateAppWidget(id, remoteViews)
}

// Create the RemoteViews for the given size.
private fun createRemoteViews(size: SizeF): RemoteViews {
}

تحديد حجم التطبيق المصغّر

يجب أن تحدّد كل أداة targetCellWidth وtargetCellHeight للأجهزة التي تعمل بنظام التشغيل Android 12 أو الإصدارات الأحدث، أو minWidth وminHeight لجميع إصدارات Android، للإشارة إلى الحد الأدنى من المساحة التي تستهلكها تلقائيًا. ومع ذلك، عندما يضيف المستخدمون تطبيقًا مصغّرًا إلى شاشتهم الرئيسية، فإنه يشغل بشكل عام أكثر من الحد الأدنى للعرض والارتفاع الذي تحدده.

توفّر شاشات Android الرئيسية للمستخدمين شبكة من المساحات المتاحة التي يمكنهم من خلالها وضع التطبيقات المصغّرة والرموز. يمكن أن تختلف هذه الشبكة حسب الجهاز، على سبيل المثال، توفّر العديد من الهواتف شبكة 5x4، ويمكن أن توفّر الأجهزة اللوحية شبكة أكبر. عند إضافة التطبيق المصغّر، يتم تمديده ليشغل الحد الأدنى من الخلايا، أفقيًا وعموديًا، المطلوبة لاستيفاء قيود targetCellWidth وtargetCellHeight على الأجهزة التي تعمل بنظام التشغيل Android 12 أو الإصدارات الأحدث، أو قيود minWidth وminHeight على الأجهزة التي تعمل بنظام التشغيل Android 11 (مستوى واجهة برمجة التطبيقات 30) أو الإصدارات الأقدم.

تختلف أبعاد الخلايا والهوامش التلقائية على الأجهزة المختلفة. استخدِم الجدول التالي لتقدير الحد الأدنى لأبعاد التطبيق المصغّر على هاتف عادي بشبكة 5×4، مع مراعاة عدد خلايا الشبكة التي تريد شغلها:

عدد الخلايا (العرض × الارتفاع) الحجم المتاح في وضع "بورتريه" (بكسل مستقل الكثافة) الحجم المتاح في الوضع الأفقي (بكسل مستقل الكثافة)
1x1 ‫57×102 بكسل مستقل الكثافة ‫127x51 بكسل مستقل الكثافة
2x1 ‫130x102 بكسل مستقل الكثافة ‫269×51 بكسل مستقل الكثافة
3x1 ‫203×102 بكسل مستقل الكثافة ‫412×51 وحدة بكسل مستقلة الكثافة
4x1 ‫276×102 بكسل مستقل الكثافة ‫554x51 بكسل مستقل الكثافة
‫5x1 ‫349×102 بكسل مستقل الكثافة 697x51dp
5x2 ‫349×220 بكسل مستقل الكثافة ‫697×117 بكسل مستقل الكثافة
5x3 ‫349×337 بكسل مستقل الكثافة ‫697×184 بكسل مستقل الكثافة
5x4 ‫349×455 بكسل مستقل الكثافة ‫697×250 بكسل مستقل الكثافة
... ... ...
n x m (73n - 16) x (118m - 16) (142n - 15) x (66m - 15)

استخدِم أحجام الخلايا في وضع &quot;بورتريه&quot; لتحديد القيم التي تقدّمها لسمات minWidth وminResizeWidth وmaxResizeWidth. وبالمثل، استخدِم أحجام خلايا الوضع الأفقي لتحديد القيم التي تقدّمها لسمات minHeight وminResizeHeight وmaxResizeHeight.

والسبب في ذلك هو أنّ عرض الخلية يكون عادةً أصغر في الوضع العمودي منه في الوضع الأفقي، وبالمثل، يكون ارتفاع الخلية عادةً أصغر في الوضع الأفقي منه في الوضع العمودي.

على سبيل المثال، إذا أردت أن يكون عرض التطبيق المصغّر قابلاً لتغيير الحجم إلى خلية واحدة على هاتف Google Pixel 4، عليك ضبط السمة minResizeWidth على 56 بكسل مستقل الكثافة كحد أقصى للتأكّد من أنّ قيمة السمة minResizeWidth أصغر من 57 بكسل مستقل الكثافة، لأنّ عرض الخلية لا يقل عن 57 بكسل مستقل الكثافة في الوضع العمودي. وبالمثل، إذا أردت أن يكون ارتفاع التطبيق المصغّر قابلاً لتغيير الحجم في خلية واحدة على الجهاز نفسه، عليك ضبط minResizeHeight على 50 بكسل مستقل الكثافة كحد أقصى للتأكّد من أنّ قيمة السمة minResizeHeight أصغر من 51 بكسل مستقل الكثافة، لأنّ ارتفاع الخلية الواحدة لا يقل عن 51 بكسل مستقل الكثافة في الوضع الأفقي.

يمكن تغيير حجم كل تطبيق مصغّر ضمن نطاقات الحجم بين السمتَين minResizeWidth/minResizeHeight وmaxResizeWidth/maxResizeHeight، ما يعني أنّه يجب أن يتكيّف مع أي نطاقات حجم بينهما.

على سبيل المثال، لضبط الحجم التلقائي للتطبيق المصغّر عند وضعه، يمكنك ضبط السمات التالية:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:targetCellWidth="3"
    android:targetCellHeight="2"
    android:minWidth="180dp"
    android:minHeight="110dp">
</appwidget-provider>

وهذا يعني أنّ الحجم التلقائي للتطبيق المصغّر هو 3×2 خلية، كما هو محدّد في السمتَين targetCellWidth وtargetCellHeight، أو 180×110 وحدة بكسل مستقلة الكثافة، كما هو محدّد في السمتَين minWidth وminHeight للأجهزة التي تعمل بنظام التشغيل Android 11 أو الإصدارات الأقدم. وفي الحالة الأخيرة، يمكن أن يختلف الحجم في الخلايا حسب الجهاز.

لضبط نطاقات الأحجام المتوافقة مع التطبيق المصغّر، يمكنك ضبط السمات التالية:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minResizeWidth="180dp"
    android:minResizeHeight="110dp"
    android:maxResizeWidth="530dp"
    android:maxResizeHeight="450dp">
</appwidget-provider>

كما هو محدّد في السمات السابقة، يمكن تغيير حجم عرض التطبيق المصغّر من 180 بكسل مستقل الكثافة إلى 530 بكسل مستقل الكثافة، ويمكن تغيير حجم ارتفاعه من 110 بكسل مستقل الكثافة إلى 450 بكسل مستقل الكثافة. يمكن بعد ذلك تغيير حجم التطبيق المصغّر من 3×2 إلى 5×2 خلية، طالما أنّ الشروط التالية متوفّرة:

val smallView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_small)
val mediumView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_medium)
val largeView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_large)

val viewMapping: Map<SizeF, RemoteViews> = mapOf(
    SizeF(180f, 110f) to smallView,
    SizeF(270f, 110f) to mediumView,
    SizeF(270f, 280f) to largeView
)

appWidgetManager.updateAppWidget(appWidgetId, RemoteViews(viewMapping))

لنفترض أنّ التطبيق المصغّر يستخدم التنسيقات المتجاوبة المحدّدة في مقتطفات الرموز البرمجية السابقة. يعني ذلك أنّ التنسيق المحدّد على أنّه R.layout.widget_weather_forecast_small يُستخدَم من 180 بكسل مستقل الكثافة (minResizeWidth) × 110 بكسل مستقل الكثافة (minResizeHeight) إلى 269×279 بكسل مستقل الكثافة (نقاط القطع التالية - 1). وبالمثل، يتم استخدام R.layout.widget_weather_forecast_medium من 270x110 بكسل مستقل الكثافة إلى 270x279 بكسل مستقل الكثافة، ويتم استخدام R.layout.widget_weather_forecast_large من 270x280 بكسل مستقل الكثافة إلى 530 بكسل مستقل الكثافة (maxResizeWidth) x‏ 450 بكسل مستقل الكثافة (maxResizeHeight).

عندما يغيّر المستخدم حجم التطبيق المصغّر، يتغيّر مظهره ليتناسب مع كل حجم في الخلايا، كما هو موضّح في الأمثلة التالية.

مثال على تطبيق مصغّر للطقس بأصغر حجم لشبكة 3x2 تعرض واجهة المستخدم اسم الموقع الجغرافي (طوكيو) ودرجة الحرارة (14 درجة مئوية) ورمزًا يشير إلى طقس غائم جزئيًا.
الشكل 2: ‫3x2 R.layout.widget_weather_forecast_small.

مثال على تطبيق مصغّر للطقس بحجم &quot;متوسط&quot; 4×2 يؤدي تغيير حجم التطبيق المصغّر
            بهذه الطريقة إلى الاستفادة من جميع عناصر واجهة المستخدم من حجم التطبيق المصغّر السابق،
            ويضيف التصنيف &quot;غائم في الغالب&quot; وتوقعات درجات الحرارة من
            الساعة 4 مساءً حتى الساعة 7 مساءً.
الشكل 3: 4x2 R.layout.widget_weather_forecast_medium.

مثال على تطبيق مصغّر للطقس بحجم &quot;متوسط&quot; 5×2 يؤدي تغيير حجم التطبيق المصغّر
            بهذه الطريقة إلى الحصول على واجهة المستخدم نفسها التي كانت في الحجم السابق، باستثناء أنّه
            يتم تمديده بمقدار طول خلية واحدة ليشغل مساحة أفقية أكبر.
الشكل 4: 5x2 R.layout.widget_weather_forecast_medium.

مثال على تطبيق مصغّر للطقس بحجم &quot;كبير&quot; يبلغ 5×3 يؤدي تغيير حجم التطبيق المصغّر
            بهذه الطريقة إلى الاستفادة من جميع عناصر واجهة المستخدم من أحجام التطبيقات المصغّرة السابقة،
            ويضيف طريقة عرض داخل التطبيق المصغّر تحتوي على توقّعات الطقس
            ليومي الثلاثاء والأربعاء. رموز تشير إلى الطقس المشمس أو الممطر
            ودرجات الحرارة العظمى والصغرى لكل يوم
الشكل 5: ‫5x3 R.layout.widget_weather_forecast_large.

مثال على تطبيق مصغّر للطقس بحجم &quot;كبير&quot; يبلغ 5×4 تغيير حجم التطبيق المصغّر
            بهذه الطريقة يعتمد على جميع عناصر واجهة المستخدم من أحجام التطبيق المصغّر السابقة،
            ويضيف يومَي الخميس والجمعة (والرموز المقابلة لهما
            التي تشير إلى نوع الطقس بالإضافة إلى درجة الحرارة العظمى والصغرى
            لكل يوم).
الشكل 6. ‫5x4 R.layout.widget_weather_forecast_large.