Pour 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 :
xWeight
etyWeight
(desfloat
s entre0
et1
) indiquent à quel endroit lier l’image au conteneurs ;fit
indique 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.scale
indique 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
app:xWeight="0.5"
app:yWeight="0.5"
app:scale="disabled"
// app:fit ne fait rien quand scale vaut "disabled"
ScaleType.CENTER_CROP
app:xWeight="0.5"
app:yWeight="0.5"
app:fit="outside"
app:scale="downscale|upscale"
ScaleType.CENTER_INSIDE
app:xWeight="0.5"
app:yWeight="0.5"
app:fit="inside"
app:scale="downscale"
ScaleType.FIT_CENTER
app:xWeight="0.5"
app:yWeight="0.5"
app:fit="inside"
app:scale="downscale|upscale"
ScaleType.FIT_END
app:xWeight="1"
app:yWeight="1"
app:fit="inside"
app:scale="downscale|upscale"
ScaleType.FIT_START
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):
git clone http://git.rom1v.com/AImageView.git
(miroir sur github)
Vous pouvez le compiler en fichier `.aar` grâce à la commande :
cd AImageView
./gradlew assembleRelease
Il 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) :
git clone --recursive http://git.rom1v.com/AImageViewSample.git
(miroir sur github)
Pour compiler un apk
de debug (par exemple) :
cd AImageViewSample
./gradlew assembleDebug
Pour 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.