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));
Я делаю это внутри адаптера.
Ответы
Ответ 1
Лучшим вариантом является подкласс ImageView
самостоятельно, переопределяя пропуск измерения:
public class SquareImageView extends ImageView {
...
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
...
}
Ответ 2
Другой ответ работает отлично. Это просто расширение решения 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, тогда эта реализация будет полезна.
Ответ 3
Еще проще:
public class SquareImageView extends ImageView {
...
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
Ответ 4
Некоторые из предыдущих ответов вполне достаточны. Я просто добавляю небольшую оптимизацию для решений @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);
}
}
}
Ответ 5
SquareImageView по указанной ширине:
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);
}
...
}
SquareImageView по указанной высоте:
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);
}
...
}
SquareImageView по минимуму размеров:
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);
}
...
}
Ответ 6
Для тех, кто ищет решение Kotlin:
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)
}
Ответ 7
если кто-то хочет, чтобы представление было не квадратным, а пропорционально изменено по высоте (например, 16/9 или 1/3), вы можете сделать это следующим образом:
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth()/3, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Ответ 8
ты можешь использовать:
Приложение: layout_constraintDimensionRatio = "1:1"
в этом случае:
<android.support.constraint.ConstraintLayout
android:id="@+id/lyt_img_cover"
android:layout_width="@dimen/image_top_episode"
android:layout_height="match_parent"
android:layout_centerInParent="false"
android:elevation="0dp"
android:foregroundGravity="center">
<ImageView
android:id="@+id/img_episode"
android:layout_width="0dp"
android:layout_height="0dp"
android:elevation="7dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</ImageView>
его расположение должно быть ConstraintLayout
и вы можете изменить ширину и высоту ConstraintLayout, однако ваш ImageView по-прежнему квадратный
Ответ 9
Здесь нет необходимости называть свой суперкласс для 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);
}