ImageView – квадрат с динамической шириной?

У меня есть GridView с ImageViews внутри. У меня 3 из них для каждой строки. Я могу правильно установить ширину с WRAP_CONTENT и scaleType = CENTER_CROP, но я не знаю, как установить размер ImageView в квадрат. Вот что я делал до сих пор, кажется, что это нормально, кроме высоты, то есть «статического»:

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

Я делаю это внутри адаптера.

Solutions Collecting From Web of "ImageView – квадрат с динамической шириной?"

Лучшим вариантом является подкласс ImageView самостоятельно, переопределяя пропуск измерения:

 public class SquareImageView extends ImageView { ... @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = getMeasuredWidth(); setMeasuredDimension(width, width); } ... } 

Другой ответ работает отлично. Это просто расширение решения bertucci для создания ImageView с квадратной шириной и высотой относительно xml-раздутого макета.

Создайте класс, скажем, SquareImageView, расширяющий ImageView, как это,

 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); } } 

Теперь, в вашем xml сделать это,

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

Если вам нужно, чтобы ImageView не был динамически создан в программе, вместо этого, чтобы быть исправленным в xml, тогда эта реализация будет полезна.

Еще проще:

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

Некоторые из предыдущих ответов вполне достаточны. Я просто добавляю небольшую оптимизацию для решений @Andro Selva и @ a.bertucci:

Это небольшая оптимизация, но проверка того, что ширина и высота различны, могут помешать другому прохождению измерений.

 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); } } } 

Здесь нет необходимости называть свой суперкласс для onMeasure . Вот моя реализация

 @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); }