2013-05-12 1 views
59

Ich habe eine GridView mit ImageViews innerhalb. Ich habe 3 von ihnen für jede Reihe. Ich kann die Breite mit WRAP_CONTENT und scaleType = CENTER_CROP korrekt einstellen, aber ich weiß nicht, wie die ImageView-Größe zu einem Quadrat festgelegt wird. Hier ist, was ich bisher getan habe, es mit Ausnahme der Höhe in Ordnung zu sein scheint, das ist „statisch“:ImageView ein Quadrat mit dynamischer Breite sein?

imageView = new ImageView(context);  
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
imageView.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT, 300)); 

ich es in einem Adapter mache.

Antwort

140

Die beste Möglichkeit ist ImageView sich, das Überschreiben der Maßübergabe Unterklasse:

public class SquareImageView extends ImageView { 

    ... 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    int width = getMeasuredWidth(); 
    setMeasuredDimension(width, width); 
    } 

    ... 

} 
+0

Super! Vielen Dank, ich habe nicht über diese Möglichkeit nachgedacht. –

+0

Wenn ich Padding // Rand einstelle, bekomme ich einen weißen Rand .. Irgendeine Idee, wie man das repariert? –

+2

android: adjustViewBounds = "true" android: scaleType = "centerCrop" @Waza_Be –

90

Die andere Antwort funktioniert gut. Dies ist nur eine Erweiterung der Bertucci-Lösung, um ein ImageView mit quadratischer Breite und Höhe in Bezug auf das xml-überhöhte Layout zu erstellen.

Erstellen Sie eine Klasse, sagen eine SquareImageView Image wie diese erstreckt,

public class SquareImageView extends ImageView { 

    public SquareImageView(Context context) { 
     super(context); 
    } 

    public SquareImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public SquareImageView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     int width = getMeasuredWidth(); 
     setMeasuredDimension(width, width); 
    } 

} 

Nun, dies in Ihrem xml tun,

 <com.packagepath.tothis.SquareImageView 
      android:id="@+id/Imageview" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" /> 

Wenn Sie eine Image müssen dynamisch Programm erstellt nicht zu Stattdessen, um in xml behoben zu werden, wird diese Implementierung hilfreich sein.

+1

Super, danke Andro. Genau das habe ich gesucht. Nochmals vielen Dank, dass Sie sich die Zeit genommen haben, eine vollständige Antwort zu geben. – Taliadon

+1

Dies sollte als die richtige, vollständige Lösung markiert werden. – JRod

+0

die für mich gearbeitet –

23

Noch einfacher:

public class SquareImageView extends ImageView { 
    ... 
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, widthMeasureSpec); 
    }  
} 
+0

für sdk vergessen Sie nicht,> = 21 @TargetApi (Build.VERSION_CODES.LOLLIPOP) öffentlichen SquareImageView (Context Kontext AttributeSet attrs, int defStyleAttr, int defStyleRes) { Super (Kontext, attrs, defStyleAttr, defStyleRes); } –

+1

@JanRabe Thx, aktualisiert. – mixel

10

Einige der bisherigen Antworten sind vollkommen ausreichend. Ich füge nur eine kleine Optimierung sowohl @Andro Selva und @ a.bertucci Lösungen hier hinzu:

Es ist eine winzige Optimierung, aber überprüfen, dass die Breite und die Höhe unterschiedlich sind, könnte einen anderen Messdurchlauf verhindern.

public class SquareImageView extends ImageView { 

    public SquareImageView(Context context) { 
     super(context); 
    } 

    public SquareImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public SquareImageView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, widthMeasureSpec); 

     int width = getMeasuredWidth(); 
     int height = getMeasuredHeight(); 

     // Optimization so we don't measure twice unless we need to 
     if (width != height) { 
      setMeasuredDimension(width, width); 
     } 
    } 

} 
-1

Hier sind alle unnötigen Aufruf seiner Oberklasse für onMeasure. Hier ist meine Implementierung

@Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int width = MeasureSpec.getSize(widthMeasureSpec); 
     int height = MeasureSpec.getSize(heightMeasureSpec); 
     int size = Math.min(width, height); 
     setMeasuredDimension(size, size); 
    }