2013-05-12 3 views
59

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

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

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

ответ

140

Наилучшим вариантом является подклассы ImageView себя, перекрывая меру проход:

public class SquareImageView extends ImageView { 

    ... 

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

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

    ... 

} 
+0

Awesome! Большое спасибо, я не думал об этой возможности. –

+0

Если я установил padding // margin, я получаю белую рамку. Любая идея, как это исправить? –

+2

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

90

Другой ответ работает отлично. Это просто расширение решения 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, тогда эта реализация будет полезна.

+1

Удивительный, спасибо Andro. Это именно то, что я искал. Опять же, спасибо за то, что нашли время, чтобы дать полный ответ. – Taliadon

+1

Это должно быть отмечено как правильное, полное решение. – JRod

+0

, что работал для меня –

23

Еще более простой:

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

не забываете для SDK> = 21 @TargetApi (Build.VERSION_CODES.LOLLIPOP) общественного SquareImageView (контекст Контекст, AttributeSet ATTRS, внутр defStyleAttr, внутр defStyleRes) { супер (контекст, ATTRS, defStyleAttr, defStyleRes); } –

+1

@JanRabe Thx, обновлено. – mixel

10

Некоторые из предыдущих ответов вполне достаточно. Я просто добавляю небольшую оптимизацию для решений @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); 
     } 
    } 

} 
-1

Здесь все излишни вызывая его суперкласс для 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); 
    } 
Смежные вопросы