ImageView:保持纵横比填充水平

8
我需要一个ImageView,将其图像缩放以填充父视图的宽度。如果图片视图的背景是红色,而其余内容(在图片下方)则是绿色,我希望得到如图片1所示的结果。这个结果可以自动获得,如果图像的宽度大于屏幕宽度。
但是,如果图片很小,比如图片2,那么我能得到的最佳结果是图片3(将ImageView的宽度和高度设置为fill_parent,并将scaleType设置为FitStart)。 图片4是通过设置height=wrap_content, width=fill_parentscaleType=CenterCrop获得的。它应该垂直缩放以显示整个图像,但正如scaleType所说,它会进行裁剪。
有什么办法可以获得图片1,即使图像很小?
将授予50个赏金给提供有效答案的人。

enter image description here


你必须从XML中完成它吗?还是可以编写代码来实现? - Asahi
如果解决方案需要代码,那就没有问题。 - Addev
1
我知道这是一个老问题,但是我因为同样的问题一直在做一些研究,这对我有用。看看这个线程,第一个答案:https://dev59.com/EnA75IYBdhLWcg3w_umD - dinigo
3个回答

4

我发现了一个对我非常有效的简单解决方案。按照您的要求设置宽度和高度,例如:

android:layout_width="fill_parent"
android:layout_height="wrap_content"

然后您还要设置这个选项:
android:adjustViewBounds="true"

"adjustViewBounds" 默认为 false(我觉得这很奇怪),但是将其设置为 true 可以轻松填充 ImageView 中的图像。


1
这是可以实现的,不需要自定义类。这是我使用小图片得到的结果: enter image description here 使用大图片: enter image description here 为了使其正常工作,您必须使用RelativeLayout,但您可以将其与LinearLayout结合使用以实现所需效果。以下是我的xml代码:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <RelativeLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <LinearLayout
            android:id="@+id/button_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_alignParentBottom="true"
            >
            <Button
                android:text="button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
            <Button
                android:text="button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
            <Button
                android:text="button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </LinearLayout>
        <ImageView 
            android:src="@drawable/cat"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:scaleType="centerCrop"
            android:layout_above="@id/button_container"/>
    </RelativeLayout>
</ScrollView>

关键在于将其设置为填充整个屏幕,但必须位于其他布局之上。这样你就可以实现你需要的一切。

使用自定义类来完成这个任务真是太棒了!但我运气不佳,因为我需要将它放在底部,而不是相反的位置... - Mia

0

试试这个:

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ViewGroup;

public class CustomImageView extends android.widget.ImageView {

    public CustomImageView(Context context) {
        super(context);
    }

    public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public CustomImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void fitYUniformly() {
        final Drawable drawable = getDrawable();
        if (drawable == null) return;

        final int dwidth = drawable.getIntrinsicWidth();
        final int dheight = drawable.getIntrinsicHeight();
        if (dwidth == -1 || dheight == -1) return;

        int vheight = this.getHeight();
        float scale = (float) vheight / (float) dheight;

        final int vwidth = (int) (dwidth * scale);
        scale(scale, vwidth, vheight);
    }

    public void fitXUniformly(int parentWidth) {
        final Drawable drawable = getDrawable();
        if (drawable == null) return;

        final int dwidth = drawable.getIntrinsicWidth();
        final int dheight = drawable.getIntrinsicHeight();
        if (dwidth == -1 || dheight == -1) return;

        int vwidth = parentWidth;// here,you need to pass the width of parentview
    //  int vwidth = this.getWidth();           
        float scale = (float) vwidth / (float) dwidth;

        final int vheight = (int) (dheight * scale);
        scale(scale, vwidth, vheight);
    }

    private void scale(float scale, int newWidth, int newHeight) {
        final ViewGroup.LayoutParams params = this.getLayoutParams();
        params.width = newWidth;
        params.height = newHeight;
        this.setLayoutParams(params);
        this.setScaleType(ScaleType.MATRIX);
        final Matrix matrix = new Matrix();
        matrix.setScale(scale, scale);
        this.setImageMatrix(matrix);
    }

}

注意:

不要忘记调用 fitXUniformly(parentWidth);。这里,parentWidth 将是 CustomImageView 的父级宽度。

希望这对你有所帮助!


这是否意味着您的代码不能直接使用?如果是这样,那么在哪里建议放置 fitXUniformly?(如您的注释中所提到的) - akhy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接