How to set both min and max size for an ImageView in Android

前端 未结 3 1814
無奈伤痛
無奈伤痛 2021-01-02 02:40

I would like so specify both min. width/height and max. width/height for an ImageView. The image should be scaled to fit.

Doing this:



        
3条回答
  •  自闭症患者
    2021-01-02 03:03

    In the end, I created my own view that extands ImageView and overwrites onMeasure():

    public class ResizingImageView extends ImageView {
    
        private int mMaxWidth;
        private int mMaxHeight;
    
        public ResizingImageView(Context context) {
            super(context);
        }
    
        public ResizingImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ResizingImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public void setMaxWidth(int maxWidth) {
            super.setMaxWidth(maxWidth);
            mMaxWidth = maxWidth;
        }
    
        @Override
        public void setMaxHeight(int maxHeight) {
            super.setMaxHeight(maxHeight);
            mMaxHeight = maxHeight;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            Drawable drawable = getDrawable();
            if (drawable != null) {
    
                int wMode = MeasureSpec.getMode(widthMeasureSpec);
                int hMode = MeasureSpec.getMode(heightMeasureSpec);
                if (wMode == MeasureSpec.EXACTLY || hMode == MeasureSpec.EXACTLY) {
                    return;
                }
    
                // Calculate the most appropriate size for the view. Take into
                // account minWidth, minHeight, maxWith, maxHeigh and allowed size
                // for the view.
    
                int maxWidth = wMode == MeasureSpec.AT_MOST
                        ? Math.min(MeasureSpec.getSize(widthMeasureSpec), mMaxWidth)
                        : mMaxWidth;
                int maxHeight = hMode == MeasureSpec.AT_MOST
                        ? Math.min(MeasureSpec.getSize(heightMeasureSpec), mMaxHeight)
                        : mMaxHeight;
    
                int dWidth = Helpers.dipsToPixels(drawable.getIntrinsicWidth());
                int dHeight = Helpers.dipsToPixels(drawable.getIntrinsicHeight());
                float ratio = ((float) dWidth) / dHeight;
    
                int width = Math.min(Math.max(dWidth, getSuggestedMinimumWidth()), maxWidth);
                int height = (int) (width / ratio);
    
                height = Math.min(Math.max(height, getSuggestedMinimumHeight()), maxHeight);
                width = (int) (height * ratio);
    
                if (width > maxWidth) {
                    width = maxWidth;
                    height = (int) (width / ratio);
                }
    
                setMeasuredDimension(width, height);
            }
        }
    }
    

    This view can now be used like:

    
    

    This works as I wanted, but shouldn't there be an easier solution?

提交回复
热议问题