AImageView (composant Android)
20 Oct 2014Pour afficher une image sur Android, le SDK contient un composant
ImageView.
Cependant, son mécanisme de configuration du redimensionnement de l’image
(ScaleType) me semble déficient :
- il ne gère pas tous les cas courants ;
- le choix de la bonne constante (si elle existe) n’est pas toujours très intuitif.
J’ai donc écrit un composant AImageView (qui hérite d’ImageView) avec un
mécanisme alternatif au scale type.
Principes
AImageView propose 4 paramètres :
xWeightetyWeight(desfloats entre0et1) indiquent à quel endroit lier l’image au conteneur ;fitindique si l’image doit s’adapter à l’intérieur du composant (en ajoutant des marges), à l’extérieur du composant (en croppant), toujours horizontalement ou toujours verticalement.scaleindique si l’on accepte de downscaler (réduire) et/ou d’upscaler (agrandir) l’image ;
Actuellement, il préserve toujours le format d’image (aspect ratio).
Exemple d’utilisation
<com.rom1v.aimageview.AImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/myimage"
app:xWeight="0.5"
app:yWeight="0.5"
app:fit="inside"
app:scale="downscale|upscale" />Ici, l’image va s’adapter à l’intérieur (inside) du composant (des marges
seront ajoutées si nécessaires), exactement (l’image peut être réduite
– downscale – ou agrandie – upscale – pour s’adapter) et sera centrée
(0.5, 0.5).
Équivalences des scale types
Les constantes de ScaleType du composant standard ImageView
correspondent en fait à des valeurs particulières de ces paramètres. Comme vous
pourrez le constater, elles ne couvrent pas toutes les combinaisons, et ne sont
pas toujours explicites…
ScaleType.CENTER
<com.rom1v.aimageview.AImageView
app:xWeight="0.5"
app:yWeight="0.5"
app:scale="disabled" />
<!-- app:fit ne fait rien quand scale vaut "disabled" -->ScaleType.CENTER_CROP
<com.rom1v.aimageview.AImageView
app:xWeight="0.5"
app:yWeight="0.5"
app:fit="outside"
app:scale="downscale|upscale" />ScaleType.CENTER_INSIDE
<com.rom1v.aimageview.AImageView
app:xWeight="0.5"
app:yWeight="0.5"
app:fit="inside"
app:scale="downscale" />ScaleType.FIT_CENTER
<com.rom1v.aimageview.AImageView
app:xWeight="0.5"
app:yWeight="0.5"
app:fit="inside"
app:scale="downscale|upscale" />ScaleType.FIT_END
<com.rom1v.aimageview.AImageView
app:xWeight="1"
app:yWeight="1"
app:fit="inside"
app:scale="downscale|upscale" />ScaleType.FIT_START
<com.rom1v.aimageview.AImageView
app:xWeight="0"
app:yWeight="0"
app:fit="inside"
app:scale="downscale|upscale" />ScaleType.FIT_XY
Cette configuration ne peut pas être reproduite en utilisant les paramètres
d’AImageView, car ce composant préserve toujours l’aspect ratio.
ScaleType.MATRIX
AImageView hérite d’ImageView et force le scaleType à ScaleType.MATRIX
(pour redimensionner et déplacer l’image). Par conséquent, il n’y a pas
d’équivalent, AImageView est basé dessus.
Composant
Le composant est disponible sous la forme d’un project library (sous licence
GNU/LGPLv3 (plus maintenant) MIT):
AImageView.
Vous pouvez le compiler en fichier .aar grâce à la commande :
cd AImageView
./gradlew assembleReleaseIl sera généré dans library/build/outputs/aar/aimageview.aar.
J’ai aussi écrit une application de démo l’utilisant (avec tous les fichiers Gradle qui-vont-bien) : AImageViewSample.
git clone --recursive https://github.com/rom1v/AImageViewSample
Pour compiler un apk de debug (par exemple) :
cd AImageViewSample
./gradlew assembleDebugPour ceux que le code intéresse, la classe principale est
AImageView. Pour l’utiliser, la partie importante est dans
activity_main.xml.
N’hésitez pas à critiquer ou à remonter des bugs.