Cette page décrit les améliorations apportées au dimensionnement des widgets et leur flexibilité accrue. introduit dans Android 12 (niveau d'API 31). Il explique également comment déterminer la taille de votre widget.
Utiliser des API améliorées pour les tailles et les mises en page de widgets
À partir d'Android 12 (niveau d'API 31), vous pouvez indiquer une taille plus affinée. et les mises en page flexibles, procédez comme suit, comme décrit dans les suivantes:
Spécifiez des contraintes de dimensionnement supplémentaires pour les widgets.
Si vous fournissez des mises en page responsives ou mises en page.
Dans les versions précédentes d'Android, il était possible d'obtenir les plages de tailles
widget à l'aide du
OPTION_APPWIDGET_MIN_WIDTH
,
OPTION_APPWIDGET_MIN_HEIGHT
,
OPTION_APPWIDGET_MAX_WIDTH
,
et OPTION_APPWIDGET_MAX_HEIGHT
puis d'estimer la taille du widget, mais cette logique ne fonctionne pas
situations différentes. Pour les widgets ciblant Android 12 ou version ultérieure, nous vous recommandons
les mots clés responsives ou exacts
mises en page.
Spécifier des contraintes de dimensionnement supplémentaires pour les widgets
Android 12 ajoute des API qui vous permettent de vous assurer que votre widget est de manière plus fiable sur des appareils avec des tailles d'écran différentes.
En plus du minWidth
existant,
minHeight
,
minResizeWidth
,
et minResizeHeight
utilisez les nouveaux attributs appwidget-provider
suivants:
targetCellWidth
ettargetCellHeight
: définir la taille cible du widget en termes de cellules de la grille du lanceur d'applications. Si défini, ces attributs sont utilisés à la place deminWidth
ouminHeight
.maxResizeWidth
etmaxResizeHeight
: définir la taille maximale à laquelle le lanceur d'applications permet de redimensionner le widget.
Le code XML suivant montre comment utiliser les attributs de dimensionnement.
<appwidget-provider
...
android:targetCellWidth="3"
android:targetCellHeight="2"
android:maxResizeWidth="250dp"
android:maxResizeHeight="110dp">
</appwidget-provider>
Fournir des mises en page responsives
Si la mise en page doit changer en fonction de la taille du widget, nous vous recommandons créant un petit ensemble de mises en page, chacune valide pour une gamme de tailles. Si cette vous pouvez aussi proposer des mises en page basées sur exactement le widget au moment de l'exécution, comme décrit sur cette page.
Cette fonctionnalité permet un scaling plus fluide et un meilleur système car le système n'a pas besoin de réactiver l'application à chaque fois le widget s'affiche dans une taille différente.
L'exemple de code suivant montre comment fournir une liste de mises en page.
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); }
Supposons que le widget présente les attributs suivants:
<appwidget-provider
android:minResizeWidth="160dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="250dp"
android:maxResizeHeight="200dp">
</appwidget-provider>
L'extrait de code précédent signifie ce qui suit:
smallView
est compatible avec une résolution de 160 dp (minResizeWidth
) × 110 dp. (minResizeHeight
) à 160 dp × 199 dp (prochain point limite : 1 dp).tallView
prend en charge de 160 dp × 200 dp à 214 dp (limite suivante - 1) × 200dp.wideView
est compatible avec une résolution comprise entre 215 dp × 110 dp (minResizeHeight
) et 250 dp. (maxResizeWidth
) × 200dp (maxResizeHeight
).
Votre widget doit prendre en charge la plage de tailles de minResizeWidth
×
minResizeHeight
à maxResizeWidth
× maxResizeHeight
. Dans cette plage,
vous pouvez décider du point limite
pour changer de mise en page.
![Exemple de mise en page responsive](https://developer.android.com/static/images/appwidgets/size-range.gif?authuser=19&hl=fr)
Fournir des mises en page exactes
Si un petit ensemble de mises en page responsives n'est pas possible, vous pouvez fournir à la place différentes mises en page adaptées aux tailles d'affichage du widget. C'est généralement deux tailles pour les téléphones (mode portrait et paysage) et quatre tailles pour appareils pliables.
Pour implémenter cette solution, votre application doit effectuer les étapes suivantes:
Surcharge
AppWidgetProvider.onAppWidgetOptionsChanged()
, qui est appelée lorsque l'ensemble des tailles change.Appelez
AppWidgetManager.getAppWidgetOptions()
, qui renvoie unBundle
contenant les tailles.Accédez à la clé
AppWidgetManager.OPTION_APPWIDGET_SIZES
à partir deBundle
.
L'exemple de code suivant montre comment fournir des mises en page exactes.
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) { }
Déterminer la taille de votre widget
Chaque widget doit définir des targetCellWidth
et des targetCellHeight
pour les appareils
Android 12 ou version ultérieure, ou minWidth
et minHeight
pour tous
versions d'Android, en indiquant la quantité minimale d'espace qu'il utilise
par défaut. Toutefois, lorsque les utilisateurs ajoutent un widget à leur écran d'accueil, il est généralement
occupent plus que la largeur et la hauteur minimales spécifiées.
Les écrans d'accueil Android proposent aux utilisateurs
une grille des espaces disponibles sur lesquels ils peuvent
placer les widgets et les icônes. Cette grille peut varier
selon l'appareil : par exemple, de nombreuses
les téléphones ont une grille de 5 x 4 et les tablettes peuvent en offrir une plus grande. Lorsque votre widget
est ajoutée, elle est étirée pour occuper le nombre minimal de cellules,
horizontalement et verticalement, afin de satisfaire aux contraintes
targetCellWidth
et targetCellHeight
sur les appareils en cours d'exécution
Android 12 ou version ultérieure, ou contraintes minWidth
et minHeight
pour
appareils équipés d'Android 11 (niveau d'API 30) ou version antérieure.
La largeur et la hauteur d'une cellule et la taille des marges automatiques appliquées aux widgets peut varier d'un appareil à l'autre. Utilisez le tableau suivant pour estimer grossièrement les dimensions minimales de votre widget dans un combiné classique à grille de 5 x 4, compte tenu de la nombre de cellules de grille occupées que vous souhaitez:
Nombre de cellules (largeur x hauteur) | Taille disponible en mode Portrait (dp) | Taille disponible en mode Paysage (dp) |
---|---|---|
1x1 | 57x102dp | 127x51dp |
2x1 | 130x102dp | 269x51dp |
3x1 | 203x102dp | 412x51dp |
4x1 | 276x102dp | 554x51dp |
5x1 | 349x102dp | 697x51dp |
5x2 | 349x220dp | 697x117dp |
5x3 | 349x337dp | 697x184dp |
5x4 | 349x455dp | 697x250dp |
... | … | ... |
n x m | (73n - 16) x (118m - 16) | (142n - 15) x (66m - 15) |
Utilisez les tailles de cellules en mode Portrait pour définir les valeurs que vous indiquez pour
les attributs minWidth
, minResizeWidth
et maxResizeWidth
. De même,
Utilisez les tailles de cellule en mode Paysage pour définir les valeurs à fournir
pour les attributs minHeight
, minResizeHeight
et maxResizeHeight
.
Cela est dû au fait que la largeur de cellule est généralement plus faible en mode Portrait qu'en mode Paysage. De même, la hauteur des cellules est généralement plus petit en mode paysage qu'en mode portrait.
Par exemple, si vous voulez que la largeur de votre widget puisse être redimensionnée pour atteindre une seule cellule
un Google Pixel 4, la résolution de votre minResizeWidth
ne doit pas dépasser 56 dp
pour vous assurer que la valeur de l'attribut minResizeWidth
est inférieure
de 57 dp, car la largeur d'une cellule en mode portrait est d'au moins 57 dp.
De même, si vous voulez que la hauteur de votre widget puisse être redimensionnée dans une cellule de la
même appareil, vous devez régler votre minResizeHeight
sur une valeur maximale de 50 dp
la valeur de l'attribut minResizeHeight
est inférieure à
51 dp, car la hauteur d'une cellule en mode Paysage est d'au moins 51 dp.
Chaque widget peut être redimensionné dans les plages de tailles comprises entre les
minResizeWidth
/minResizeHeight
et maxResizeWidth
/maxResizeHeight
ce qui signifie qu'il doit s'adapter à toutes les plages de tailles qui les séparent.
Par exemple, pour définir la taille par défaut du widget lors de l'emplacement, vous pouvez Définissez les attributs suivants:
<appwidget-provider
android:targetCellWidth="3"
android:targetCellHeight="2"
android:minWidth="180dp"
android:minHeight="110dp">
</appwidget-provider>
Cela signifie que la taille par défaut du widget est de 3 x 2 cellules, comme spécifié par
les attributs targetCellWidth
et targetCellHeight
, ou 180 × 110 dp,
spécifié par minWidth
et minHeight
pour les appareils
Android 11 ou version antérieure Dans ce dernier cas, la taille
des cellules peut
varient en fonction de l'appareil.
Pour définir les plages de tailles compatibles avec votre widget, vous pouvez également définir les paramètres suivants : Attributs:
<appwidget-provider
android:minResizeWidth="180dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="530dp"
android:maxResizeHeight="450dp">
</appwidget-provider>
Comme indiqué par les attributs précédents, la largeur du widget est de 180 dp à 530 dp, et sa hauteur peut être redimensionnée de 110 dp à 450 dp. Il est alors possible de redimensionner les cellules de 3 x 2 à 5 x 2, à condition que les conditions suivantes sont présentes:
- L'appareil dispose d'une grille de 5 x 4.
- Mappage entre le nombre de cellules et la taille disponible en dp respecte le tableau indiquant l'estimation du nombre dimensions de cette page.
- Le widget s'adapte à cette plage de tailles.
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);
Supposons que le widget utilise les mises en page responsives définies à l'étape précédente
extraits de code. Cela signifie que la mise en page spécifiée
R.layout.widget_weather_forecast_small
est utilisé à partir de 180 dp (minResizeWidth
) x
110 dp (minResizeHeight
) à 269 x 279 dp (prochains limites - 1). De même,
R.layout.widget_weather_forecast_medium
est utilisé entre 270 x 110 dp et 270 x 279 dp.
et R.layout.widget_weather_forecast_large
est utilisé pour les valeurs comprises entre 270 x 280 dp et
530dp (maxResizeWidth
) x 450dp (maxResizeHeight
).
Lorsque l'utilisateur redimensionne le widget, son apparence change pour s'adapter à chaque taille dans cellules, comme illustré dans les exemples suivants.
![Exemple de widget météo dans la plus petite taille de grille 3 x 2 L'UI montre
le nom du lieu (Tokyo), la température (14°) et un symbole indiquant
un temps partiellement nuageux.](https://developer.android.com/static/images/appwidgets/weather-size-3x2.png?authuser=19&hl=fr)
R.layout.widget_weather_forecast_small
.![Exemple de widget météo dans un format "medium" 4x2 la taille de l'image. Redimensionner le widget
de cette façon, s'appuie sur toute l'interface utilisateur
de la taille de widget précédente,
et ajoute l'étiquette "Globalement nuageux" et une prévision
des températures de
entre 16h et 19h.](https://developer.android.com/static/images/appwidgets/weather-size-4x2.png?authuser=19&hl=fr)
R.layout.widget_weather_forecast_medium
4 x 2.![Exemple de widget météo dans une image "medium" de 5 x 2 la taille de l'image. Redimensionner le widget
Cela donne la même interface utilisateur que la taille précédente, sauf qu'il s'agit
étirée d’une longueur de cellule
pour occuper plus d’espace horizontal.](https://developer.android.com/static/images/appwidgets/weather-size-5x2.png?authuser=19&hl=fr)
R.layout.widget_weather_forecast_medium
5 x 2.![Exemple de widget météo dans un grand modèle 5x3 "large" la taille de l'image. Redimensionner le widget
de cette façon, s'appuie sur toutes les interfaces
des tailles de widget précédentes,
et ajoute une vue dans le widget avec les prévisions météo
le mardi et
le mercredi. Symboles indiquant un temps ensoleillé ou pluvieux
et les températures maximale et minimale
chaque jour.](https://developer.android.com/static/images/appwidgets/weather-size-5x3.png?authuser=19&hl=fr)
R.layout.widget_weather_forecast_large
5 x 3.![Exemple de widget météo en taille "L" 5 x 4 la taille de l'image. Redimensionner le widget
de cette façon, s'appuie sur toutes les interfaces
des tailles de widget précédentes,
et ajoute les jeudis et vendredis (et leurs symboles correspondants)
indiquant le type de météo ainsi que les températures maximale et basse
pour chaque jour).](https://developer.android.com/static/images/appwidgets/weather-size-5x4.png?authuser=19&hl=fr)
R.layout.widget_weather_forecast_large
5 x 4.