it-swarm.com.de

ImageView ein Quadrat mit dynamischer Breite sein?

Ich habe eine GridView mit ImageViews im Inneren. 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 ich die Größe der ImageView auf ein Quadrat einstellen soll. Folgendes habe ich bisher gemacht, es scheint in Ordnung zu sein, mit Ausnahme der Höhe, die "statisch" ist:

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

Ich mache es in einem Adapter.

70
Andrea

Die beste Option ist, ImageView selbst zu unterklassifizieren und den Kennzahlendurchlauf zu überschreiben:

public class SquareImageView  extends ImageView {

  ...

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

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

  ...

}
163
a.bertucci

Die andere Antwort funktioniert gut. Dies ist nur eine Erweiterung von Bertuccis Lösung, um eine ImageView mit quadratischer Breite und Höhe in Bezug auf das aufgeblasene XML-Layout zu erstellen.

Erstellen Sie eine Klasse, sagen Sie eine SquareImageView, die ImageView wie folgt erweitert:

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 tun Sie dies in Ihrem XML,

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

Wenn Sie eine ImageView benötigen, die nicht dynamisch im Programm erstellt, sondern in XML repariert werden soll, ist diese Implementierung hilfreich.

95
Andro Selva

Noch einfacher:

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

Einige der vorherigen Antworten sind völlig ausreichend. Ich füge hier nur eine kleine Optimierung zu den Lösungen von @Andro Selva und @ a.bertucci hinzu:

Es ist eine winzige Optimierung, aber die Überprüfung, ob Breite und Höhe unterschiedlich sind, kann einen weiteren 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);
        }
    }

}
11
Chantell Osejo

Eine squareImageView mit der angegebenen Breite:

public class SquareImageViewByWidth extends AppCompatImageView {

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

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

    public SquareImageViewByWidth(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

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

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

     ...
}

Eine squareImageView mit der angegebenen Höhe:

    public class SquareImageViewByHeight extends AppCompatImageView {

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

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

        public SquareImageViewByHeight(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }

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

            int height = getMeasuredHeight();
            setMeasuredDimension(height, height);
        }

        ...
    }

Ein squareImageView mit einem Minimum an Abmessungen:

public class SquareImageViewByMin extends AppCompatImageView {

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

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

        public SquareImageViewByHeight(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }

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

       ...
    }
3
Misagh

Für diejenigen, die eine Kotlin-Lösung suchen:

class SquareImageView @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
) : ImageView(context, attrs, defStyleAttr, defStyleRes){
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) = super.onMeasure(widthMeasureSpec, widthMeasureSpec)
}

wenn jemand möchte, dass die Ansicht nicht quadratisch ist, sondern proportional in der Höhe geändert wird (z. B. 16/9 oder 1/3), können Sie dies folgendermaßen tun:

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth()/3, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
1
John