【问题标题】:ImageView: fill horizontal maintaining aspect ratioImageView:填充水平保持纵横比
【发布时间】:2012-03-26 06:32:29
【问题描述】:

我需要一个ImageView 缩放它的图像,直到水平填充父级。

如果 imageview 背景为红色,而其余内容(图片下方)为绿色,我正在寻找 图片 1 所示的结果。如果图像宽度高于屏幕宽度,则会自动获得该结果。

但如果是像图 2 中的小图。我能得到的最好结果是 图 3(将 ImageView 的宽度和高度设置为 fill_parent 和scaleType 为 FitStart

图片4是在height= wrap_content, width= fill_parent,scaleType= CenterCrop的设置下获得的。它应该垂直缩放以显示整个图像,但正如 scaleType 所说,它会裁剪它。

即使图像很小也可以获得图片 1 的任何想法?

将奖励 50 给一个有效的答案

【问题讨论】:

  • 你必须从 XML 中完成,还是也可以是代码?
  • 用代码解决就没有问题
  • 我知道这是一个老问题,但我一直在做一些研究,因为你有同样的问题,这对我有用。看看这个帖子,第一个回答:stackoverflow.com/questions/2991110/…

标签: android layout android-layout imageview


【解决方案1】:

我找到了一个非常适合我的简单解决方案。根据需要设置宽度和高度,例如:

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

那么你也设置了这个设置:

android:adjustViewBounds="true"

“adjustViewBounds”默认为 false(我觉得这很奇怪),但设置它可以很容易地在 imageview 中填充图像。

【讨论】:

    【解决方案2】:

    没有自定义类也是可行的。这是我用小图像获得的结果:

    大图:

    您必须使用 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>
    

    诀窍是您将其设置为填满屏幕,但它必须位于其他布局之上。这样您就可以实现所需的一切。

    【讨论】:

    • 在没有自定义类的情况下做到这一点真是太棒了!我运气不好,因为我需要把它放在底部,正好相反......
    【解决方案3】:

    试试这个:

    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 的位置在哪里? (如您的笔记中所述)
    猜你喜欢
    • 2012-08-23
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多