ImageView scales to a fixed height but excess crop width

I would like mine to ImageViewscale in a certain way:

  • Scale so that the height of the image always matches the height ImageView
  • Trim excess width

The image speaks louder than 1000 words, so it shows how I want mine ImageViewto behave. Suppose it has a fixed height of 100dp, and let its width be equal match_parent.

enter image description here

note that

  • on the layout of the phone, the image height is stretched, but the sides are cropped, akin CROP_CENTER.
  • on the layout of the tablet, the image is also stretched to fit the height ImageView, likeFIT_CENTER

, scaleType:matrix, . , Y, X?

+4
4

ImageView:

public class FitYCropXImageView extends ImageView {
    boolean done = false;

    @SuppressWarnings("UnusedDeclaration")
    public FitYCropXImageView(Context context) {
        super(context);
        setScaleType(ScaleType.MATRIX);
    }

    @SuppressWarnings("UnusedDeclaration")
    public FitYCropXImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setScaleType(ScaleType.MATRIX);
    }

    @SuppressWarnings("UnusedDeclaration")
    public FitYCropXImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setScaleType(ScaleType.MATRIX);
    }

    private final RectF drawableRect = new RectF(0, 0, 0,0);
    private final RectF viewRect = new RectF(0, 0, 0,0);
    private final Matrix m = new Matrix();
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (done) {
            return;//Already fixed drawable scale
        }
        final Drawable d = getDrawable();
        if (d == null) {
            return;//No drawable to correct for
        }
        int viewHeight = getMeasuredHeight();
        int viewWidth = getMeasuredWidth();
        int drawableWidth = d.getIntrinsicWidth();
        int drawableHeight = d.getIntrinsicHeight();
        drawableRect.set(0, 0, drawableWidth, drawableHeight);//Represents the original image
        //Compute the left and right bounds for the scaled image
        float viewHalfWidth = viewWidth / 2;
        float scale = (float) viewHeight / (float) drawableHeight;
        float scaledWidth = drawableWidth * scale;
        float scaledHalfWidth = scaledWidth / 2;
        viewRect.set(viewHalfWidth - scaledHalfWidth, 0, viewHalfWidth + scaledHalfWidth, viewHeight);

        m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER /* This constant doesn't matter? */);
        setImageMatrix(m);

        done = true;

        requestLayout();
    }
}
+4

xml :

    android:scaleType="centerCrop"
    android:adjustViewBounds="true"

: fooobar.com/questions/345751/...

+7

If you are using scaleType:matrix, you will need to create your own Matrix and assign it to the view using setImageMatrix(Matrix)or manually change the matrix in the henMedia method for customImageView.

public class MyImageView extends ImageView   {

 boolean done=false;

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

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (done)
            return;

        final Drawable d = getDrawable();
        final int drawableW = d.getIntrinsicWidth();
        final int drawableH = d.getIntrinsicHeight();
        float ratio =  drawableW / drawableH;

        //int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        float scale=height/drawableH;

          Matrix m = getImageMatrix();

          float[] f = new float[9];
          m.getValues(f);

          f[Matrix.MSCALE_X]=scale;
          f[Matrix.MSCALE_Y]=scale;

          m.setValues(f);  

        done = true;

        requestLayout();

    }

}
+1
source
    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);
    LayoutParams params;

    final ImageView iv0 = new ImageView(this);
    //iv0.setBackgroundColor(0xffff0000);
    params = new LayoutParams(LayoutParams.MATCH_PARENT, 100);
    ll.addView(iv0, params);

    final ImageView iv1 = new ImageView(this);
    //iv1.setBackgroundColor(0xff00ff00);
    params = new LayoutParams(60, 100);
    ll.addView(iv1, params);

    setContentView(ll);

    Runnable action = new Runnable() {
        @Override
        public void run() {
            Drawable d = getResources().getDrawable(R.drawable.layer0);
            int dw = d.getIntrinsicWidth();
            int dh = d.getIntrinsicHeight();
            RectF src = new RectF(0, 0, dw, dh);

            ImageView[] iviews = {iv0, iv1};
            for (int i = 0; i < iviews.length; i++) {
                ImageView iv = iviews[i];
                iv.setImageDrawable(d);
                iv.setScaleType(ScaleType.MATRIX);

                float h = iv.getHeight();
                float w = iv.getWidth();
                float cx = w / 2;
                float scale = h / dh;
                float deltaw = dw * scale / 2;
                RectF dst = new RectF(cx - deltaw, 0, cx + deltaw, h);
                Matrix m = new Matrix();
                m.setRectToRect(src, dst, ScaleToFit.FILL);
                iv.setImageMatrix(m);
            }
        }
    };
    iv1.post(action);
+1
source

Source: https://habr.com/ru/post/1524240/


All Articles