Android XML - 在保持任何宽度比的同时具有ImageView填充高度

时间:2016-11-09 05:16:22

标签: android xml imageview

我正在构建Android应用程序,现在正在设计用户个人资料活动。

它应该在一个看起来像横幅的矩形容器的顶部显示个人资料图片。

<ImageView
android:id="@+id/user_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:layout_centerHorizontal="true"
android:elevation="2dp"/>

如果图像的比例为1x1或者高度大于宽度,则此XML代码可以正常工作。 (我在背景中显示相同图像的模糊和拉伸版本,因此它并不完全丑陋)。

我遇到的问题 WIDTH大于HEIGHT 的时候。它试图缩放高度(在我的情况下为300dp),但随后宽度击中布局的边框并停止调整大小,在图像下留下一个空白区域。

知道 scaleType =“centerCrop”几乎与我正在寻找的东西相比,但是如果图像的比例是1x1就会裁剪这个人的形象的顶部(大多数时候是头发),我不想要。

基本上,在XML或JAVA中是否有办法调整图像的高度以填充我的容器,同时保持宽度比并忽略父布局的最大宽度? (我想它应该会像“centerCrop”那样裁剪溢出的东西。

这是我正在实现的目标和问题的图像。灰色部分是同一图像的模糊和调整大小的版本,因此当图像无法填充宽度时(例如,在1x1比例图片中),它看起来不太难看。 https://i.stack.imgur.com/FUDcP.png

3 个答案:

答案 0 :(得分:0)

我没有正确使用您,但您希望保持图像的宽高比,您应该match_parentandroid:height并尝试wrap_content宽度ImageView。尝试fitCenter作为android:scaleType

尝试下面的代码 -

<ImageView
        android:id="@+id/user_pic"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:scaleType="fitCenter"
        android:adjustViewBounds="true"
        android:background="@android:color/transparent"/>

答案 1 :(得分:0)

答案是在this link找到的。

基本上,使用的技巧是用Java创建自定义ImageView类,然后使用它。如有必要,它将根据情况计算正确的裁剪区域。

如果有人找到纯XML解决方案,请随时告诉我!

没有任何进一步的等待,这是我使用的代码。

JAVA CLASS

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

<强> XML

<com.app.YourAppName.YourAppName.CustomViews.FitYCropXImageView
                        android:id="@+id/user_pic"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="@android:color/transparent"
                        android:elevation="2dp"
                        />

必要的JAVA活动

import com.app.YourAppName.YourAppName.CustomViews.FitYCropXImageView;

FitYCropXImageView profilePic = (FitYCropXImageView) findViewById(R.id.user_pic);

答案 2 :(得分:0)

如果您的ImageView宽度为match_parent且您的原始图像大小为300x400

并且还假设Deice的WIDTH_PIXEL 1080和HEIGHT_PIXEL 1920

您的ImageView需要为1080x1440(3:4)

你可以使用如下。

public static final int WIDTH_PIXEL = Resources.getSystem().getDisplayMetrics().widthPixels;
public static final int HEIGHT_PIXEL = Resources.getSystem().getDisplayMetrics().heightPixels;

//ratioX : ratioY = givenX : X
public static int getRatio(int ratioX, int ratioY, int givenX) {
    int result = (int) ((((float) ratioY * (float) givenX) / (float) ratioX) + 0.5f);
    //Log.v(TAG, "Request -> " + ratioX + " : " + ratioY + " = " + givenX + " : " + result);
    return result;
}


{//Usage
   int width = 300;
   int height = 400;

   int resultHeight = getRatio(width, height , WIDTH_PIXEL);
   myImageVIew.getLayoutParams().height = resultHeight ;
}


<ImageView  
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>    

我希望它能成为你的暗示。