簡體   English   中英

ImageView 縮放到固定高度,但裁剪多余的寬度

[英]ImageView to scale to fixed height, but crop excess width

我希望我的ImageView以特定方式擴展:

  • 縮放使圖像的高度始終適合ImageView的高度
  • 裁剪任何多余的寬度

圖片勝於千言萬語,下面是我希望我的ImageView表現如何的表示。 假設它的高度固定為 100dp,寬度為match_parent

在此處輸入圖像描述

注意

  • 在手機布局上,圖像高度被拉伸,但邊被裁剪,類似於CROP_CENTER
  • 在平板電腦布局上,圖像也被拉伸以適應ImageView高度,表現得像FIT_CENTER

我懷疑我需要scaleType:matrix ,但在那之后我迷路了。 如何確保圖像適合 Y,但裁剪 X?

在xml中,使用:

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

來自並感謝: https//stackoverflow.com/a/15600295/2162226

在朋友Carlos Robles和pskink的幫助下,想出了以下自定義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();
    }
}

如果使用scaleType:matrix ,則需要創建自己的Matrix並通過setImageMatrix(Matrix)將其指定給視圖,或者在customImageView的hen onMEasure方法中手動修改矩陣。

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

    }

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

如果要顯示圖像的中心,請使用:

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

如果要顯示圖像的邊緣而不是中心,請使用:

android:scaleType="matrix"
android:adjustViewBounds="true"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM