ImageView be a square with dynamic width?
Solution 1
The best option is to subclass ImageView
yourself, overriding the measure pass:
public class SquareImageView extends ImageView {
...
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
...
}
Solution 2
The other answer works fine. This is just an extension of bertucci's solution to make an ImageView with square width and height with respect to xml inflated layout.
Create a class, say a SquareImageView extending ImageView like this,
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);
}
}
Now, in your xml do this,
<com.packagepath.tothis.SquareImageView
android:id="@+id/Imageview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
If you need an ImageView not to be dynamically created in program, instead, to be fixed in xml, then this implementation will be helpful.
Solution 3
Even more simple:
public class SquareImageView extends ImageView {
...
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
Solution 4
Several of the previous answers are perfectly sufficient. I'm just adding a small optimization to both @Andro Selva and @a.bertucci's solutions here:
It's a tiny optimization, but checking that the width and the height are different could prevent another measurement pass.
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);
}
}
}
Solution 5
For those looking for a Kotlin solution:
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)
}
Comments
-
Andrea almost 2 years
I have a GridView with ImageViews inside. I have 3 of them for each row. I can set correctly the width with WRAP_CONTENT and scaleType = CENTER_CROP, but I don't know how to set the ImageView's size to be a square. Here's what I did until now, it seems to be ok except the height, that is "static":
imageView = new ImageView(context); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT, 300));
I'm doing it inside an adapter.
-
Andrea about 11 yearsAwesome! Thank you very much, I didn't think about this possibility
-
Waza_Be almost 11 yearsIf I set padding // margin, I get a white border.. Any idea how to fix that?
-
Taliadon over 10 yearsAwesome, thank you Andro. This is precisely what I was looking for. Again, thanks for taking the time to provide a complete answer.
-
Kaloyan Roussev over 10 yearsandroid:adjustViewBounds="true" android:scaleType="centerCrop" @Waza_Be
-
Jarrod Robins almost 10 yearsThis should be marked as the correct, full solution.
-
Mehdiway about 9 yearsThat's the most beautiful fix I've ever seen. Thank you ! :)
-
android developer about 9 yearsShouldn't it be set as the min(width,height) instead?
-
Chantell Osejo almost 9 yearsIt's a tiny optimization, but checking that the width and the height are different could prevent another measurement pass. @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = getMeasuredWidth(); int height = getMeasuredHeight(); // Optimization so we don't measure twice unless we need to if (width != height) { setMeasuredDimension(width, width); } }
-
Jan Rabe over 8 yearsdon't forget for sdk >= 21 @TargetApi(Build.VERSION_CODES.LOLLIPOP) public SquareImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); }
-
Pullat Junaid almost 6 yearsAnswer is explained in this page codesofjunaid.blogspot.com/2017/04/…
-
Richard Le Mesurier over 5 yearsThe use of
AppCompatImageView
in this answer is an important point. -
Mr-IDE over 2 yearsSee also a good tutorial that uses this technique: raywenderlich.com/…