Android

Créer des bitmaps à partir de Jetpack Composables

Le 31 juillet 2021 - 5 minutes de lecture

 

Il existe plusieurs approches pour créer des bitmaps, notamment :

  • Utilisez un canevas et dessinez tout à l’aide de commandes API primitives

Il existe plusieurs articles sur Stackoverflow qui couvrent tout sauf la dernière suggestion, car Compose est encore nouveau à ce stade. Si votre mise en page est très simple, utiliser une mise en page XML ou créer une vue par programmation peut faire l’affaire. L’utilisation de vues dans l’ancien système de vues ne nécessite pas que la vue soit affichée ou même attachée à une fenêtre. Mais si votre mise en page est assez complexe, utiliser une vue peut être fastidieux. L’utilisation d’une toile est peut-être la pire approche car elle nécessite beaucoup plus de codage et a tendance à agir davantage comme une peinture. Vous pouvez prendre un instantané si vous pouvez visualiser la mise en page. Il existe de nombreux cas, comme le mien, où vous ne voulez pas vraiment afficher la mise en page et la mise en page est assez complexe.

Ayant travaillé avec Compose au cours des 6 derniers mois, je peux attester que c’est une bien meilleure approche pour la mise en page d’un écran qu’avec l’ancien système de visualisation. Ainsi, il devient naturel de penser que la création d’un bitmap à partir d’un composite serait la voie à suivre. Mais après avoir lutté avec cela pendant quelques jours, il est devenu clair que la génération du bitmap n’était pas exactement un processus simple.

Dans une application Android entièrement créée à l’aide de Jetpack Compose, il n’y a qu’une seule vue dans l’application, qui est la vue racine de l’activité. La manière typique de créer un bitmap à l’aide du système de visualisation consiste à dessiner la visualisation sur un canevas. Voici le code que j’utilise pour gérer cela:

Comme déjà mentionné, vous pouvez fournir une vue créée par programme mais non ajoutée au canevas. Il s’avère que vous ne pouvez pas le faire en utilisant un composite. Un composable ne sera rendu que lorsqu’il est attaché à une fenêtre. Le composable n’a pas besoin d’être visible, mais doit être attaché à une fenêtre. La fenêtre doit contenir un ViewTreeLifecycleOwner utilisé par Compose pour déterminer quand recomposer le composant.

Pendant un certain temps, j’ai eu du mal à comprendre comment attacher un composé à une fenêtre qui n’est pas réellement affichée. Une fenêtre, cependant, ne peut être créée qu’en créant une activité. Cela semblait exclure la possibilité pour un composite d’être rendu sans l’attacher à une activité réelle.

J’ai donc commencé à réfléchir à la façon dont je pourrais attacher un composé à une activité, mais pas l’afficher, mais le faire restituer. Heureusement, Jetpack Compose prend en charge l’intégration de vues dans des vues compostables et composables dans des vues. Après mûre réflexion, j’ai trouvé une solution qui nécessite d’utiliser les deux approches pour obtenir une composition rendue sans l’afficher. La vue personnalisée, cependant il doit encore être ajouté à l’activité.

La solution pour générer le bitmap à partir d’un composable sans afficher le composable peut être résumée avec ces étapes :

  1. Créez une vue personnalisée et ajoutez-y un ComposeView. Définissez sa propriété de visibilité sur « gone » pour garder la vue masquée. Appelez la fonction setContent dans ComposeView à l’intérieur de la vue personnalisée et fournissez la disposition combinable à l’intérieur de setContent qui sera rendue dans le bitmap.

Pour créer une vue personnalisée, créez simplement une classe qui étend une disposition primitive. Dans cet exemple, j’utilise LinearLayoutCompat. Peu importe ce que vous utilisez, l’aperçu ne s’affichera pas :

CatInfo est le composite que j’utilise et sera utilisé pour rendre la mise en page bitmap. Il est important de noter que lors de la création d’un bitmap, vous devez spécifier la largeur et la hauteur du bitmap. Vous devez également spécifier la hauteur et la largeur de son parent correspondant pour l’empêcher de dépasser les limites du bitmap. Dans cet exemple, cela ne me dérange pas car je connais la taille de l’image et je me suis assuré que la taille du bitmap sera suffisamment grande pour éviter tout recadrage.

O viewTreeObserver.addOnGlobalLayoutListener est nécessaire pour déterminer quand la vue personnalisée a terminé le rendu. Ce n’est qu’alors que l’aperçu peut être converti en bitmap.

Lorsque le bitmap a été créé, le surBitmapCréé le rappel sera appelé pour fournir au client le bitmap généré. Ce rappel est juste un moyen de fournir le bitmap à votre client. La manière dont vous fournissez le bitmap à votre client dépend de vous. J’ai choisi de le faire de cette façon car bien que le bitmap n’ait pas besoin d’être affiché, pour cet exemple, je voulais l’afficher pour montrer les résultats.

IMPORTANT

Si vous devez passer des paramètres à votre composable, il est important où et comment vous définissez ces paramètres. On ne sait pas pourquoi certains cas échouent à compiler. Cela semble être un bogue dans le compilateur Kotlin et/ou Jetpack Compose, car ces défauts ne s’appliquent que lors de l’intégration d’un composite dans une vue personnalisée. Voici quelques exemples de ce qui sera compilé et de ce qui échouera lors de l’utilisation de paramètres :

Utilisez AndroidView dans votre activité pour intégrer votre vue personnalisée :

Commentaires

Laisser un commentaire

Votre commentaire sera révisé par les administrateurs si besoin.