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

تصف هذه الصفحة التحسينات الخاصة بحجم الأدوات والمرونة الأكبر تم طرحه في Android 12 (المستوى 31). كما يشرح بالتفصيل كيفية تحديد حجم الأداة.

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

بدءًا من الإصدار Android 12 (المستوى 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
  ...
  android:targetCellWidth="3"
  android:targetCellHeight="2"
  android:maxResizeWidth="250dp"
  android:maxResizeHeight="110dp">
</appwidget-provider>

توفير تخطيطات سريعة الاستجابة

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

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

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

Kotlin

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

    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)
}

Java

@Override
public void onUpdate(...) {
    RemoteViews smallView = ...;
    RemoteViews tallView = ...;
    RemoteViews wideView = ...;

    Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>();
    viewMapping.put(new SizeF(150f, 100f), smallView);
    viewMapping.put(new SizeF(150f, 200f), tallView);
    viewMapping.put(new SizeF(215f, 100f), wideView);
    RemoteViews remoteViews = new RemoteViews(viewMapping);

    appWidgetManager.updateAppWidget(id, remoteViews);
}

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

<appwidget-provider
    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

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

Kotlin

override fun onAppWidgetOptionsChanged(
        context: Context,
        appWidgetManager: AppWidgetManager,
        id: Int,
        newOptions: Bundle?
) {
    super.onAppWidgetOptionsChanged(context, appWidgetManager, id, newOptions)
    // Get the new sizes.
    val sizes = newOptions?.getParcelableArrayList<SizeF>(
            AppWidgetManager.OPTION_APPWIDGET_SIZES
    )
    // 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 { }

Java

@Override
public void onAppWidgetOptionsChanged(
    Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
    super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
    // Get the new sizes.
    ArrayList<SizeF> sizes =
        newOptions.getParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES);
    // Check that the list of sizes is provided by the launcher.
    if (sizes == null || sizes.isEmpty()) {
      return;
    }
    // Map the sizes to the RemoteViews that you want.
    Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>();
    for (SizeF size : sizes) {
        viewMapping.put(size, createRemoteViews(size));
    }
    RemoteViews remoteViews = new RemoteViews(viewMapping);
    appWidgetManager.updateAppWidget(id, remoteViews);
}

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

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

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

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

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

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

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

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

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

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

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

<appwidget-provider
    android:targetCellWidth="3"
    android:targetCellHeight="2"
    android:minWidth="180dp"
    android:minHeight="110dp">
</appwidget-provider>

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

بالإضافة إلى ذلك، لضبط نطاقات الحجم المتوافقة مع أداتك، يمكنك تحديد ما يلي: :

<appwidget-provider
    android:minResizeWidth="180dp"
    android:minResizeHeight="110dp"
    android:maxResizeWidth="530dp"
    android:maxResizeHeight="450dp">
</appwidget-provider>

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

Kotlin

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))

Java

RemoteViews smallView = 
    new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_small);
RemoteViews mediumView = 
    new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_medium);
RemoteViews largeView = 
    new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_large);

Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>();
viewMapping.put(new SizeF(180f, 110f), smallView);
viewMapping.put(new SizeF(270f, 110f), mediumView);
viewMapping.put(new SizeF(270f, 280f), largeView);
RemoteViews remoteViews = new RemoteViews(viewMapping);

appWidgetManager.updateAppWidget(id, remoteViews);

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

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

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

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

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

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

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