En esta página, se describen las mejoras en el tamaño del widget y su flexibilidad. se introdujo en Android 12 (nivel de API 31). También detalla cómo determinar un tamaño para tu widget.
Cómo usar API mejoradas para tamaños y diseños de widgets
A partir de Android 12 (nivel de API 31), puedes proporcionar un tamaño más definido atributos y diseños flexibles, haz lo siguiente, como se describe en el a continuación:
Especifica restricciones adicionales para el tamaño de widgets.
Proporcionar diseños adaptables o diseños y diseños.
En versiones anteriores de Android, es posible obtener los rangos de tamaño de un
con el
OPTION_APPWIDGET_MIN_WIDTH
:
OPTION_APPWIDGET_MIN_HEIGHT
,
OPTION_APPWIDGET_MAX_WIDTH
,
y OPTION_APPWIDGET_MAX_HEIGHT
extras y luego estimar el tamaño del widget, pero esa lógica no funciona en todos
situaciones. Para los widgets que se orientan a Android 12 o versiones posteriores, te recomendamos
que proporcionan anuncios responsivos o
los diseños.
Cómo especificar restricciones adicionales para el tamaño de widgets
En Android 12, se agregan APIs que te permiten garantizar que tu widget de manera más confiable en distintos dispositivos con distintos tamaños de pantalla.
Además de los atributos existentes minWidth
, minHeight
, minResizeWidth
y minResizeHeight
, usa los siguientes atributos appwidget-provider
nuevos:
targetCellWidth
ytargetCellHeight
: definen el tamaño de destino del widget en términos de las celdas de cuadrícula del selector. Si se definen estos atributos, se usan en lugar deminWidth
ominHeight
.maxResizeWidth
ymaxResizeHeight
: definir el tamaño máximo al que el selector le permite al usuario cambiar el tamaño del widget.
En el siguiente XML, se muestra cómo usar los atributos de tamaño.
<appwidget-provider
...
android:targetCellWidth="3"
android:targetCellHeight="2"
android:maxResizeWidth="250dp"
android:maxResizeHeight="110dp">
</appwidget-provider>
Cómo brindar diseños responsivos
Si el diseño necesita cambiar en función del tamaño del widget, te recomendamos que crees un conjunto pequeño de diseños y que cada uno sea válido para una variedad de tamaños. Si esta no es posible, otra opción es brindar diseños basados en el widget exacto durante el tiempo de ejecución, como se describe en esta página.
Esta función permite un escalamiento más fluido y un mejor rendimiento del sistema ya que el sistema no tiene que activar la app cada vez se muestra el widget en un tamaño diferente.
En el siguiente ejemplo de código, se muestra cómo brindar una lista de diseños.
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); }
Supongamos que el widget tiene los siguientes atributos:
<appwidget-provider
android:minResizeWidth="160dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="250dp"
android:maxResizeHeight="200dp">
</appwidget-provider>
El fragmento de código anterior significa lo siguiente:
smallView
admite desde 160 dp (minResizeWidth
) × 110 dp (minResizeHeight
) a 160 dp × 199 dp (próximo punto de corte: 1 dp).tallView
admite desde 160 dp × 200 dp hasta 214 dp (próximo punto de corte: 1) × 200dp.wideView
admite desde 215 dp × 110 dp (minResizeHeight
) hasta 250 dp (maxResizeWidth
) × 200 dp (maxResizeHeight
)
Tu widget debe admitir un rango de tamaño de minResizeWidth
× X
minResizeHeight
a maxResizeWidth
× maxResizeHeight
. Dentro de ese rango,
puedes decidir el punto de corte para cambiar de diseño.
![Ejemplo de diseño responsivo](https://developer.android.google.cn/static/images/appwidgets/size-range.gif?authuser=9&hl=es)
Cómo brindar diseños exactos
Si no es posible proporcionar un conjunto pequeño de diseños responsivos, en su lugar, puedes brindar diferentes diseños que se adapten a los tamaños en los que se muestra el widget. Suelen ser dos tamaños para teléfonos (modo de retrato y de paisaje) y cuatro tamaños para dispositivos plegables.
Para implementar esta solución, la app debe realizar los siguientes pasos:
Sobrecargar a
AppWidgetProvider.onAppWidgetOptionsChanged()
, al que se llama cuando cambia el conjunto de tamaños.Llamar a
AppWidgetManager.getAppWidgetOptions()
, que muestraBundle
con los tamaños.Acceder a la clave
AppWidgetManager.OPTION_APPWIDGET_SIZES
desdeBundle
.
En el siguiente ejemplo de código, se muestra cómo brindar diseños exactos.
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) { }
Determina el tamaño de tu widget
Cada widget debe definir un targetCellWidth
y un targetCellHeight
para los dispositivos.
que ejecuten Android 12 o versiones posteriores, o minWidth
y minHeight
para todos
de Android, lo que indica la cantidad mínima de espacio que consume
de forma predeterminada. Sin embargo, cuando los usuarios agregan un widget a su pantalla principal, por lo general,
Ocupa más que el ancho y la altura mínimos que especifiques.
Las pantallas de inicio de Android ofrecen a los usuarios una cuadrícula de espacios disponibles en los que pueden
los widgets y los iconos de Google Places. Esta cuadrícula puede variar según el dispositivo. por ejemplo, muchos
los teléfonos celulares ofrecen una cuadrícula de 5x4, y las tablets pueden ofrecer una cuadrícula más grande. Cuando el widget
se expande para que ocupe el número mínimo de celdas,
horizontal y verticalmente, para cumplir con las restricciones de su
targetCellWidth
y targetCellHeight
en dispositivos que ejecutan
Android 12 o versiones posteriores, o restricciones de minWidth
y minHeight
en
dispositivos con Android 11 (nivel de API 30) o versiones anteriores.
El ancho y la altura de una celda y el tamaño de los márgenes automáticos aplicados a widgets puede variar según el dispositivo. Usa la siguiente tabla para hacer una estimación aproximada las dimensiones mínimas del widget en un teléfono típico con cuadrícula de 5x4, según la cantidad de celdas de cuadrícula ocupadas que deseas:
Número de celdas (ancho x alto) | Tamaño disponible en modo vertical (dp) | Tamaño disponible en modo horizontal (dp) |
---|---|---|
1 × 1 | 57 × 102 dp | 127 × 51 dp |
2 × 1 | 130x102dp | 269x51dp |
3 × 1 | 203x102dp | 412x51dp |
4 × 1 | 276x102dp | 554x51dp |
5 × 1 | 349x102dp | 697x51dp |
5 × 2 | 349x220dp | 697 × 117 dp |
5 × 3 | 349x337dp | 697 × 184 dp |
5 × 4 | 349 × 455 dp | 697 × 250 dp |
… | … | … |
n × m | (73n - 16) x (118m - 16) | (142n - 15) x (66m - 15) |
Usa los tamaños de celda en modo vertical para informar los valores que proporciones
los atributos minWidth
, minResizeWidth
y maxResizeWidth
De forma similar,
use los tamaños de celda en modo horizontal para informar los valores que proporcione
para los atributos minHeight
, minResizeHeight
y maxResizeHeight
.
Esto se debe a que el ancho de las celdas suele ser menor en el modo vertical. que en el modo horizontal y, de manera similar, la altura de la celda suele ser más pequeña en el modo horizontal que en el vertical.
Por ejemplo, si quieres que el tamaño del widget se pueda reducir a una celda en
un Google Pixel 4, debes configurar tu minResizeWidth
en 56 dp como máximo
para asegurarte de que el valor del atributo minResizeWidth
sea menor
que 57 dp, porque una celda tiene al menos 57 dp de ancho en el modo vertical.
Del mismo modo, si quieres que la altura del widget pueda cambiar de tamaño en una celda, en la
del mismo dispositivo, debes configurar tu minResizeHeight
en 50 dp como máximo para asegurarte de que
el valor del atributo minResizeHeight
es menor que
51 dp, porque una celda tiene al menos 51 dp de altura en el modo horizontal
Se puede modificar el tamaño de cada widget dentro de los intervalos de tamaño entre los
minResizeWidth
/minResizeHeight
y maxResizeWidth
/maxResizeHeight
atributos, lo que significa que debe adaptarse a cualquier rango de tamaño entre ellos.
Por ejemplo, para establecer el tamaño predeterminado del widget en la posición, puedes configura los siguientes atributos:
<appwidget-provider
android:targetCellWidth="3"
android:targetCellHeight="2"
android:minWidth="180dp"
android:minHeight="110dp">
</appwidget-provider>
Esto significa que el tamaño predeterminado del widget es de 3x2 celdas, según se especifica en el
atributos targetCellWidth
y targetCellHeight
, o 180 × 110 dp, como
especificado por minWidth
y minHeight
para dispositivos que ejecutan
Android 11 o versiones anteriores En este último caso, el tamaño en las celdas puede
varían según el dispositivo.
Además, para configurar los rangos de tamaño admitidos de tu widget, puedes establecer lo siguiente atributos:
<appwidget-provider
android:minResizeWidth="180dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="530dp"
android:maxResizeHeight="450dp">
</appwidget-provider>
Como se especifica en los atributos anteriores, el ancho del widget es puede cambiar de tamaño de 180 dp a 530 dp y su altura puede cambiar de 110 dp a 450 dp. El tamaño del widget se puede cambiar de 3x2 a 5x2 celdas, siempre que se cumpla lo siguiente están presentes:
- El dispositivo tiene una cuadrícula de 5 × 4.
- La asignación entre la cantidad de celdas y el tamaño disponible en dps sigue la tabla que muestra la estimación del valor mínimo dimensiones de esta página.
- El widget se adapta a ese rango de tamaño.
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);
Supón que el widget usa los diseños responsivos definidos en el ejemplo anterior
fragmentos de código. Esto significa que el diseño especificado como
R.layout.widget_weather_forecast_small
se utiliza desde 180 dp (minResizeWidth
) x
De 110 dp (minResizeHeight
) a 269 x 279 dp (próximo punto de corte: 1) De forma similar,
R.layout.widget_weather_forecast_medium
se usa de 270 x 110 dp a 270 x 279 dp.
y R.layout.widget_weather_forecast_large
se usa de 270 x 280 dp a
530 dp (maxResizeWidth
) x 450 dp (maxResizeHeight
)
A medida que el usuario modifica el tamaño del widget, su apariencia cambia para adaptarse a cada tamaño en celdas existentes, como se muestra en los siguientes ejemplos.
![Ejemplo de widget del clima en el tamaño de cuadrícula más pequeño de 3x2. La IU muestra
el nombre de la ubicación (Tokio), la temperatura (14°) y el símbolo que indica
clima parcialmente nublado.](https://developer.android.google.cn/static/images/appwidgets/weather-size-3x2.png?authuser=9&hl=es)
R.layout.widget_weather_forecast_small
.![Ejemplo de widget del clima en un elemento “medium” de 4 x 2 de tamaño del ensamble. Cambia el tamaño del widget
de esta manera se basa en toda la IU del tamaño del widget anterior,
y agrega la etiqueta “Mayormente nublado” y un pronóstico de las temperaturas de
De 4 p.m. a 7 p.m.](https://developer.android.google.cn/static/images/appwidgets/weather-size-4x2.png?authuser=9&hl=es)
R.layout.widget_weather_forecast_medium
.![Ejemplo de widget del clima en un elemento “medium” de 5 × 2 de tamaño del ensamble. Cambia el tamaño del widget
de esta manera da como resultado la misma IU que el tamaño anterior, con la excepción
estirado por una longitud de celda para ocupar más espacio horizontal.](https://developer.android.google.cn/static/images/appwidgets/weather-size-5x2.png?authuser=9&hl=es)
R.layout.widget_weather_forecast_medium
.![Ejemplo de widget del clima en un tamaño grande de 5 x 3 de tamaño del ensamble. Cambia el tamaño del widget
de esta manera se basa en toda la IU de los tamaños de widgets anteriores,
y agrega una vista dentro del widget que contiene un pronóstico del clima
el martes y el miércoles. Símbolos que indican clima soleado o lluvioso
y temperaturas máximas y mínimas de cada día.](https://developer.android.google.cn/static/images/appwidgets/weather-size-5x3.png?authuser=9&hl=es)
R.layout.widget_weather_forecast_large
.![Ejemplo de widget del clima en un dispositivo “grande” de 5x4 de tamaño del ensamble. Cambia el tamaño del widget
de esta manera se basa en toda la IU de los tamaños de widgets anteriores,
y agrega el jueves y el viernes (y sus símbolos correspondientes
que indican el tipo de clima, así como la temperatura máxima y mínima
para cada día).](https://developer.android.google.cn/static/images/appwidgets/weather-size-5x4.png?authuser=9&hl=es)
R.layout.widget_weather_forecast_large
.