Può capitare, sviluppando una app per dispositivi Android, di avere l'esigenza di estendere le dimensioni di una immagine in modo da farle coprire orizzontalmente tutto lo schermo disponibile, mantenendo inalterate le sue proporzioni. Questo significa che l'altezza dell'immagine suddetta dovrà adattarsi in modo proporzionale alla larghezza, così da mantenere inalterato l'aspect ratio originario.
Il problema
Ottenere questo risultato in HTML è estremamente semplice: è sufficiente impostare la width dell'immagine in questione al 100%, omettendo qualsiasi informazione in merito alla height e lasciando così che sia il browser a determinarla in modo proporzionale. Sfortunatamente, in Android la questione è più complessa: nell'elemento ImageView altezza e larghezza sono due parametri obbligatori, che è possibile valorizzare con un numero fisso in px, dp o altro, in base al contenitore mediante il comando match_parent oppure in base al contenuto mediante il comando wrap_content. In tutti e tre i casi non è possibile definire un comportamento dell'altezza realmente proporzionale rispetto al contenuto. Il meglio che è possibile fare utilizzando una normale ImageView è impostare gli attributi android:layout_width, android:layout_height e android:scaleType in modo che si adattino automaticamente alle dimensioni del layout contenitore nel seguente modo:
1 2 3 4 5 6 |
<ImageView android:id="@+id/myImage" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitCenter" /> |
Questo metodo consente di ottenere il risultato sperato nella maggior parte degli scenari, ma ha il grande difetto di non funzionare allo stesso modo su tutti i dispositivi Android e con tutte le immagini.
La soluzione
Chi ha detto che è necessario utilizzare una normale ImageView? Questo interessantissimo post su StackOverflow mostra come è possibile estendere una View per ottenere un risultato analogo a quello che stiamo cercando. Partendo da quell'esempio possiamo quindi sviluppare una estensione della classe ImageView che dimensioni automaticamente l'altezza sulla base del ridimensionamento della larghezza in modo proporzionale rispetto all'aspect ratio dell'immagine originaria.
Questo il codice completo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.my.namespace; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.ImageView; public class ProportionalImageView extends ImageView { public ProportionalImageView(Context context) { super(context); } public ProportionalImageView(Context context, AttributeSet attrs) { super(context, attrs); } public ProportionalImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Drawable d = getDrawable(); if (d != null) { int w = MeasureSpec.getSize(widthMeasureSpec); int h = w * d.getIntrinsicHeight() / d.getIntrinsicWidth(); setMeasuredDimension(w, h); } else super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } |
E questa è l'implementazione all'interno di un layout XML:
1 2 3 4 5 6 7 8 9 |
<com.my.namespace.ProportionalImageView android:id="@+id/img" android:src="@drawable/myCustomImage" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:adjustViewBounds="true" /> |
Ricordate, in entrambi gli esempi, di sostituire com.my.namespace con il namespace utilizzato nella vostra applicazione.
Felice sviluppo!