2011-09-20 12 views
18

Ho un'immagine che è più piccola del contenitore che mi piacerebbe inserire all'interno. Vorrei che l'immagine si allungasse, mantenendo le sue proporzioni, alla sua dimensione più grande possibile.Come rendere l'immagine più grande possibile mantenendo le proporzioni

Per illustrare questo problema:

<ImageView android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:src="@drawable/thumbnail" 
      android:scaleType="fitXY" 
      android:adjustViewBounds="true"/> 

Il ImageView sopra dovrebbe essere allungato per riempire la larghezza del contenitore. Il @drawable che conteneva si estendeva anche lungo l'asse x per adattarsi alla larghezza di ImageView che è perfetto. Tuttavia, il problema è che la dimensione denominata wrap_content, in questo caso l'altezza, rimane delle stesse dimensioni dell'altezza iniziale di @drawable s.

Ho letto la documentazione relativa a ScaleType here e non riesco a trovare la risposta lì.

L'immagine seguente descrive il codice sopra:

enter image description hereenter image description here

Current behaviour    Desired Behaviour 

Modifica

Un ImageView dato scaleType="fitCenter" sarà accuratamente espandere/ridurre il @drawable all'interno di esso a crescere il più grande possibile, pur mantenendo ing è proporzioni.

Le dimensioni di ImageView s sono definite prima che lo @drawable venga ridimensionato in alcun modo. Le dimensioni di ImageView non sono influenzate dal ridimensionamento dello stesso contenuto in @drawable.

+2

Per me, questo è un problema comune, uno per il quale non ho mai trovato una soluzione pulita. Aggiungi una patch di sfondo 9 per un frame, ed è ancora peggio tentare di risolvere il problema. Sono abbastanza sicuro che questo è qualcosa che devi fare a livello di programmazione, ma sarà bello se qualcuno ha una soluzione per questo. – kcoppock

+2

+1 per una domanda completamente descritta – Merlin

risposta

7

XML

L'unica soluzione a questo in XML è quello di utilizzare "match_parent" o un valore massimo discreto anziché "wrap_content" ove possibile. Ciò assicurerà che la dimensione ImageView sia corretta, il che significa che l'aggiunta di scaleType="fitCenter" assicurerà che lo @drawable verrà quindi ridimensionato correttamente.

Programatically

E 'brutto, ma è possibile ridimensionare l'ImageView dopo che è dimensioni stato dato valori discreti:

final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail); 

    ViewTreeObserver thumbnailViewVto = thumbnailView.getViewTreeObserver(); 
    thumbnailViewVto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
     private boolean changed = false; 
     @Override 
     public void onGlobalLayout() { 
      if(!changed) { 
       Drawable image = getResources().getDrawable(R.drawable.thumbnail); 
       float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight(); 
       int height = thumbnailView.getHeight(); 

       thumbnailView.setLayoutParams(
         new LayoutParams(
           (int) (height * heighToWidthRatio), height)); 
       changed = true; 
      } 
     } 
    }); 

EDIT

final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail); 

    thumbnailView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

     @Override 
     public void onGlobalLayout() { 
      // Remove the GlobalOnLayout Listener so it only fires once. 
      thumbnailView.getViewTreeObserver().removeGlobalOnLayoutListener(this) 

      // Find the images Height to Width ratio 
      Drawable image = getResources().getDrawable(R.drawable.thumbnail); 
      float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight(); 

      // Use this ratio to discover the ratio of the ImageView to allow it to perfectly contain the image. 
      int height = thumbnailView.getHeight(); 
      thumbnailView.setLayoutParams(new LayoutParams(
           (int) (height * heighToWidthRatio), height)); 
     } 
    }); 
+1

+1 per risolvere un problema comune – Merlin

+0

Per che cosa è booleano 'cambiato'? – BornToCode

+0

È così che il listener onGlobalLayout non si attiva ripetutamente. Più vecchio e più saggio, ora rimuoverò il 'OnGlobalLayoutListener' dal' ViewTreeObserver' come prima azione nel metodo 'onGlobalLayout()'. (Vedi la mia modifica per i dettagli) – Graeme

1

Sembra che si voglia fitCenter, che utilizza Matrix.ScaleToFit CENTER.

+0

Questo keep è il rapporto aspetto ma l'immagine non si riempie più.Ciò funzionerebbe se l'altezza di ImageView fosse corretta, operazione che può essere eseguita in modo programmatico ma vorrei che avvenga tramite XML. – Graeme

+0

@Graeme - Dal link: "Calcola una scala che manterrà le proporzioni src originali, ma assicurerà anche che src si adatti interamente al dst. * Almeno un asse (X o Y) si adatterà esattamente. * Il risultato è centrato dentro dst. " - La loro descrizione sembra implicare che l'immagine sarà allungata per riempire la larghezza o l'altezza. Forse si restringe solo per adattarsi, ma non si allunga per adattarsi? – mbeckish

+0

Questa descrizione è esatta: poiché una delle dimensioni è impostata su "wrap_content", tuttavia, l'inizializzazione della dimensione di ImageView sembra avvenire prima del ridimensionamento, pertanto l'altezza della vista è già impostata e utilizza l'asse più piccolo per adattarsi a , senza ingrandirlo. – Graeme

Problemi correlati