ImageView be a square with dynamic width?

2019-01-03 13:40发布

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.

8条回答
小情绪 Triste *
2楼-- · 2019-01-03 14:13

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)
}
查看更多
Ridiculous、
3楼-- · 2019-01-03 14:13

if someone wants the view to be not square, but proportionally resized in height (for example, 16/9 or 1/3), you can do it like this:

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth()/3, MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
查看更多
小情绪 Triste *
4楼-- · 2019-01-03 14:18

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

  ...

}
查看更多
Ridiculous、
5楼-- · 2019-01-03 14:20

Even more simple:

public class SquareImageView extends ImageView {
    ...
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
    }    
}
查看更多
Explosion°爆炸
6楼-- · 2019-01-03 14:21

An squareImageView by specified width:

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 widthMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

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

     ...
}

An squareImageView by specified height:

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

        ...
    }

An squareImageView by minimum of dimentions:

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

       ...
    }
查看更多
Juvenile、少年°
7楼-- · 2019-01-03 14:25

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.

查看更多
登录 后发表回答