طرح بندی ویجت های انعطاف پذیر را ارائه دهید

این صفحه اصلاحات مربوط به اندازه ویجت و انعطاف پذیری بیشتر معرفی شده در Android 12 (سطح API 31) را شرح می دهد. همچنین نحوه تعیین اندازه ویجت خود را شرح می دهد.

از API های بهبود یافته برای اندازه و طرح بندی ویجت ها استفاده کنید

با شروع Android 12 (سطح API 31)، می‌توانید با انجام کارهای زیر، ویژگی‌های اندازه دقیق‌تر و طرح‌بندی‌های انعطاف‌پذیر را ارائه دهید، همانطور که در بخش‌های زیر توضیح داده شده است:

  1. محدودیت های اضافی اندازه ویجت را مشخص کنید.

  2. ارائه طرح‌بندی‌های واکنش‌گرا یا طرح‌بندی دقیق.

در نسخه‌های قبلی Android، می‌توان با استفاده از OPTION_APPWIDGET_MIN_WIDTH ، OPTION_APPWIDGET_MIN_HEIGHT ، OPTION_APPWIDGET_MAX_WIDTH ، محدوده اندازه یک ویجت را دریافت کرد و OPTION_APPWIDGET_MAX_HEIGHT اندازه‌های اضافی را تخمین زد. برای ابزارک‌هایی که Android 12 یا بالاتر را هدف قرار می‌دهند، توصیه می‌کنیم طرح‌بندی‌های واکنش‌گرا یا دقیق ارائه کنید.

محدودیت های اضافی اندازه ویجت را مشخص کنید

Android 12 API هایی را اضافه می کند که به شما امکان می دهد اندازه ویجت خود را در دستگاه های مختلف با اندازه های مختلف صفحه نمایش با اطمینان بیشتری اندازه کنید.

علاوه بر ویژگی‌های 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>

طرح‌بندی‌های واکنش‌گرا را ارائه دهید

اگر نیاز است که چیدمان بسته به اندازه ویجت تغییر کند، توصیه می‌کنیم مجموعه کوچکی از طرح‌بندی‌ها ایجاد کنید که هر کدام برای طیف وسیعی از اندازه‌ها معتبر هستند. اگر این امکان پذیر نیست، گزینه دیگری ارائه طرح بندی بر اساس اندازه دقیق ویجت در زمان اجرا است، همانطور که در این صفحه توضیح داده شده است.

این ویژگی اجازه می دهد تا مقیاس نرم تر و به طور کلی سلامت سیستم بهتر شود، زیرا سیستم مجبور نیست هر بار که ویجت را در اندازه های مختلف نمایش می دهد، برنامه را بیدار کند.

مثال کد زیر نحوه ارائه لیستی از طرح بندی ها را نشان می دهد.

کاتلین

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

جاوا

@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 از 160dp ( minResizeWidth ) × 110dp ( minResizeHeight ) تا 160dp × 199dp (نقطه برش بعدی - 1dp) پشتیبانی می کند.
  • tallView از 160dp × 200dp تا 214dp (نقطه برش بعدی - 1) × 200dp را پشتیبانی می کند.
  • wideView از 215dp × 110dp ( minResizeHeight ) تا 250dp ( maxResizeWidth ) × 200dp ( maxResizeHeight ) را پشتیبانی می کند.

ویجت شما باید محدوده اندازه از minResizeWidth × minResizeHeight تا maxResizeWidth × maxResizeHeight را پشتیبانی کند. در آن محدوده، می‌توانید نقطه برش را برای تغییر طرح‌بندی تعیین کنید.

نمونه ای از طرح بندی واکنش گرا
شکل 1. نمونه ای از یک طرح پاسخگو.

طرح بندی های دقیق را ارائه دهید

اگر مجموعه کوچکی از طرح‌بندی‌های پاسخگو امکان‌پذیر نیست، در عوض می‌توانید طرح‌بندی‌های مختلفی را متناسب با اندازه‌هایی که ویجت در آن نشان داده می‌شود، ارائه دهید. این معمولاً دو اندازه برای تلفن ها (حالت عمودی و افقی) و چهار اندازه برای گوشی های تاشو است.

برای پیاده سازی این راه حل، برنامه شما باید مراحل زیر را انجام دهد:

  1. Overload 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?.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 { }

جاوا

@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 را برای دستگاه‌های دارای Android 12 یا بالاتر - یا minWidth و minHeight برای همه نسخه‌های Android - تعریف کند که نشان‌دهنده حداقل فضایی است که به طور پیش‌فرض مصرف می‌کند. با این حال، هنگامی که کاربران ویجت را به صفحه اصلی خود اضافه می کنند، معمولاً بیش از حداقل عرض و ارتفاعی که شما مشخص می کنید اشغال می کند.

صفحه‌های اصلی اندروید شبکه‌ای از فضاهای موجود را به کاربران ارائه می‌دهند که می‌توانند ویجت‌ها و نمادها را روی آن قرار دهند. این شبکه می تواند بسته به دستگاه متفاوت باشد. به عنوان مثال، بسیاری از گوشی ها شبکه 5x4 را ارائه می دهند و تبلت ها می توانند شبکه بزرگتری ارائه دهند. هنگامی که ویجت شما اضافه می‌شود، به‌گونه‌ای کشیده می‌شود که حداقل تعداد سلول‌ها را به صورت افقی و عمودی اشغال کند که برای برآورده کردن محدودیت‌های targetCellWidth و targetCellHeight آن در دستگاه‌های دارای Android 12 یا بالاتر، یا محدودیت‌های minWidth و minHeight در دستگاه‌های دارای Android 11 (API) لازم است. سطح 30) یا پایین تر.

هم عرض و ارتفاع یک سلول و هم اندازه حاشیه‌های خودکار اعمال شده برای ویجت‌ها می‌تواند در دستگاه‌ها متفاوت باشد. از جدول زیر برای تخمین تقریبی حداقل ابعاد ویجت خود در یک گوشی شبکه معمولی 5×4 با توجه به تعداد سلول های شبکه اشغال شده مورد نظر خود استفاده کنید:

تعداد سلول ها (عرض x ارتفاع) اندازه موجود در حالت عمودی (dp) اندازه موجود در حالت افقی (dp)
1x1 57x102dp 127x51dp
2x1 130x102dp 269x51dp
3x1 203x102dp 412x51dp
4x1 276x102dp 554x51dp
5×1 349x102dp 697x51dp
5×2 349x220dp 697x117dp
5×3 349x337dp 697x184dp
5×4 349x455dp 697x250dp
... ... ...
nxm (73n - 16) x (118m - 16) (142n - 15) x (66m - 15)

از اندازه سلول های حالت عمودی برای اطلاع دادن مقادیری که برای ویژگی های minWidth ، minResizeWidth و maxResizeWidth ارائه می کنید، استفاده کنید. به طور مشابه، از اندازه سلول های حالت افقی برای اطلاع دادن مقادیری که برای ویژگی های minHeight ، minResizeHeight و maxResizeHeight ارائه می کنید، استفاده کنید.

دلیل این امر این است که عرض سلول معمولاً در حالت عمودی کمتر از حالت افقی است - و به طور مشابه، ارتفاع سلول معمولاً در حالت افقی کمتر از حالت عمودی است.

به عنوان مثال، اگر می‌خواهید اندازه ویجت شما تا یک سلول در Google Pixel 4 قابل تغییر باشد، باید minResizeWidth خود را حداکثر روی 56dp تنظیم کنید تا مطمئن شوید که مقدار ویژگی minResizeWidth کوچکتر از 57dp است—زیرا یک سلول حداقل 57dp عرض در پرتره. به طور مشابه، اگر می خواهید ارتفاع ویجت شما در یک سلول در همان دستگاه قابل تغییر اندازه باشد، باید minResizeHeight خود را حداکثر روی 50dp تنظیم کنید تا مطمئن شوید که مقدار مشخصه minResizeHeight کوچکتر از 51dp است – زیرا یک سلول حداقل 51dp است. در حالت افقی بالا

هر ویجت در محدوده اندازه بین ویژگی های 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×110dp، همانطور که توسط minWidth و minHeight برای دستگاه‌های دارای Android 11 یا پایین‌تر مشخص شده است. در مورد دوم، اندازه سلول ها می تواند بسته به دستگاه متفاوت باشد.

همچنین، برای تنظیم محدوده اندازه های پشتیبانی شده ویجت خود، می توانید ویژگی های زیر را تنظیم کنید:

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

همانطور که توسط ویژگی های قبلی مشخص شده است، عرض ویجت از 180dp به 530dp قابل تغییر است و ارتفاع آن از 110dp به 450dp قابل تغییر است. سپس ویجت از سلول های 3x2 به 5x2 قابل تغییر اندازه است، تا زمانی که شرایط زیر وجود داشته باشد:

کاتلین

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

جاوا

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 از 180dp ( minResizeWidth ) x 110dp ( minResizeHeight ) تا 269x279dp (نقاط برش بعدی - 1) استفاده می شود. به طور مشابه، R.layout.widget_weather_forecast_medium از 270x110dp تا 270x279dp، و R.layout.widget_weather_forecast_large از 270x280dp تا 530dp ( maxResizeWidth ) استفاده می‌شود ( maxResizeHeight )

همانطور که در مثال های زیر نشان داده شده است، همانطور که کاربر اندازه ویجت را تغییر می دهد، ظاهر آن برای انطباق با هر اندازه در سلول ها تغییر می کند.

ویجت نمونه آب و هوا در کوچکترین اندازه شبکه 3x2. رابط کاربری نام مکان (توکیو)، دما (14 درجه) و نمادی را نشان می دهد که هوای نیمه ابری را نشان می دهد.
شکل 2. 3x2 R.layout.widget_weather_forecast_small .

ویجت نمونه آب و هوا در اندازه «متوسط» 4×2. تغییر اندازه ویجت به این ترتیب بر روی تمام رابط کاربری از اندازه ویجت قبلی است و برچسب "بیشتر ابری" و پیش بینی دما از ساعت 4 بعد از ظهر تا 7 بعد از ظهر را اضافه می کند.
شکل 3. 4x2 R.layout.widget_weather_forecast_medium .

ویجت نمونه آب و هوا در اندازه «متوسط» 5×2. تغییر اندازه ویجت به این ترتیب باعث ایجاد رابط کاربری مشابه با اندازه قبلی می شود، با این تفاوت که به اندازه یک سلول کشیده می شود تا فضای افقی بیشتری را اشغال کند.
شکل 4. 5x2 R.layout.widget_weather_forecast_medium .

ویجت نمونه آب و هوا در اندازه بزرگ 5x3. تغییر اندازه ویجت به این ترتیب بر روی تمام رابط کاربری اندازه های قبلی ویجت ایجاد می شود و نمای داخل ویجت حاوی پیش بینی آب و هوا در روزهای سه شنبه و چهارشنبه اضافه می کند. نمادهایی که هوای آفتابی یا بارانی و دمای بالا و پایین را برای هر روز نشان می دهند.
شکل 5. 5x3 R.layout.widget_weather_forecast_large .

ویجت نمونه آب و هوا در اندازه بزرگ 5x4. تغییر اندازه ویجت به این ترتیب بر روی تمام رابط کاربری اندازه های قبلی ویجت ایجاد می شود و پنجشنبه و جمعه را اضافه می کند (و نمادهای مربوط به آنها که نوع آب و هوا و همچنین دمای بالا و پایین را برای هر روز نشان می دهد) اضافه می کند.
شکل 6. 5x4 R.layout.widget_weather_forecast_large .