ImageView的将规模扩大到一定的高度,但裁剪多余的宽度宽度、多余、高度、规模

2023-09-07 14:44:29 作者:tā是wifi我却不是手机

我想我的 的ImageView 规模以特殊的方式:

I would like my ImageView to scale in a particular fashion:

在规模,使图像的高度总适合的高度的ImageView 裁剪多余的宽度

一个画面讲比1000字更响亮,所以这里是我多么希望我的的ImageView 来表现重新presentation。假设它有一个固定的高度说100dp并假设其宽度 match_parent

A picture speaks louder than a 1000 words, so here is a representation of how I want my ImageView to behave. Suppose it has a fixed height of say 100dp and suppose its width is match_parent.

注意

在手机布局,图像高度被拉伸,但双方都裁剪,类似于 CROP_CENTER 。 在平板电脑的布局,也被形象地拉伸以适应的ImageView 的高度,表现得像 FIT_CENTER on the phone layout, the image height is stretched, but the sides are cropped, akin to CROP_CENTER. on the tablet layout, the image is also stretched to fit the ImageView height, behaving like FIT_CENTER

我怀疑我需要 scaleType:矩阵,但我失去了在那之后。我怎样才能确保图片符合Y,但作物X'

I suspect I need scaleType:matrix, but after that I'm lost. How can I make sure an image fits Y, but crops X?

推荐答案

通过我的朋友卡洛斯·罗伯斯和pskink一点帮助,想出了下面的自定义的ImageView

With a little help from my friends Carlos Robles and pskink, came up with the following custom 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();
    }
}