ImageView - 高度匹配宽度?

时间:2012-03-21 03:55:31

标签: android

我有一个imageview。我希望它的宽度为fill_parent。我希望它的高度无论宽度最终如何。例如:

<ImageView
  android:layout_width="fill_parent"
  android:layout_height="whatever the width ends up being" />

在布局文件中是否可以这样,而不必创建自己的视图类?

由于

14 个答案:

答案 0 :(得分:136)

更新:2017年9月14日

根据下面的评论,从Android支持库26.0.0开始,不推荐使用百分比支持库。这是实现它的新方法:

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1:1" />

</android.support.constraint.ConstraintLayout>

请参阅here

<强>推荐使用:

根据Android开发者的this post,您现在需要做的就是在PercentRelativeLayout或PercentFrameLayout中包装您想要的任何内容,然后指定其比率,如此

<android.support.percent.PercentRelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        app:layout_widthPercent="100%"
        app:layout_aspectRatio="100%"/>

</android.support.percent.PercentRelativeLayout>

答案 1 :(得分:93)

也许这会回答你的问题:

<ImageView
    android:id="@+id/cover_image"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true" />

您可以忽略此特定情况的scaleType属性。

答案 2 :(得分:30)

这可以使用LayoutParams在运行时知道视图宽度后动态设置视图高度。您需要使用Runnable线程才能在运行时获取Views宽度,否则您将在知道View的宽度之前尝试设置Height,因为尚未绘制布局。

我如何解决问题的示例:

final FrameLayout mFrame = (FrameLayout) findViewById(R.id.frame_id);

    mFrame.post(new Runnable() {

        @Override
        public void run() {
            RelativeLayout.LayoutParams mParams;
            mParams = (RelativeLayout.LayoutParams) mFrame.getLayoutParams();
            mParams.height = mFrame.getWidth();
            mFrame.setLayoutParams(mParams);
            mFrame.postInvalidate();
        }
    });

LayoutParams必须是您的视图所在的父视图的类型。我的FrameLayout位于xml文件中的RelativeLayout内。

    mFrame.postInvalidate();
调用

以强制视图在与UI线程不同的线程上重绘

答案 3 :(得分:13)

在这里,我做了一个ImageButton,它的宽度总是等于它的高度(并避免在一个方向上的愚蠢的空边距......我认为这是一个SDK的bug ...):

我定义了一个从ImageButton扩展的SquareImageButton类:

package com.myproject;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageButton;

    public class SquareImageButton extends ImageButton {

        public SquareImageButton(Context context) {
        super(context);


        // TODO Auto-generated constructor stub
    }

    public SquareImageButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub

    }

    public SquareImageButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub

    }

    int squareDim = 1000000000;

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


        int h = this.getMeasuredHeight();
        int w = this.getMeasuredWidth();
        int curSquareDim = Math.min(w, h);
        // Inside a viewholder or other grid element,
        // with dynamically added content that is not in the XML,
        // height may be 0.
        // In that case, use the other dimension.
        if (curSquareDim == 0)
            curSquareDim = Math.max(w, h);

        if(curSquareDim < squareDim)
        {
            squareDim = curSquareDim;
        }

        Log.d("MyApp", "h "+h+"w "+w+"squareDim "+squareDim);


        setMeasuredDimension(squareDim, squareDim);

    }

}

这是我的xml:

<com.myproject.SquareImageButton
            android:id="@+id/speakButton"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:scaleType="centerInside"
            android:src="@drawable/icon_rounded_no_shadow_144px"
            android:background="#00ff00"
            android:layout_alignTop="@+id/searchEditText"
            android:layout_alignBottom="@+id/searchEditText"
            android:layout_alignParentLeft="true"
           />

像魅力一样!

答案 4 :(得分:10)

我无法让David Chu's answer为RecyclerView项目工作,并想出我需要将ImageView约束到父级。将ImageView宽度设置为0dp并将其开始和结束约束为父级。我不确定在某些情况下将宽度设置为wrap_contentmatch_parent是否有效,但我认为这是让ConstraintLayout的子节点填充其父节点的更好方法。

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintDimensionRatio="1:1"/>

</android.support.constraint.ConstraintLayout>

答案 5 :(得分:5)

你不能单独使用布局,我试过了。我最后编写了一个非常简单的类来处理它,你可以在github上查看它。 SquareImage.java它是一个更大的项目的一部分,但没有任何一点复制和粘贴无法修复(在Apache 2.0下许可)

基本上你只需要设置高度/宽度等于另一个尺寸(取决于你想要缩放它的方式)

注意:您可以使用scaleType属性在没有自定义类的情况下使其成为正方形,但视图的边界超出可见图像范围,如果您将其他视图放在其附近,则会出现问题。

答案 6 :(得分:4)

在Android 26.0.0中PercentRelativeLayout has been deprecated

解决问题的最佳方法是ConstraintLayout,如下所示:

<android.support.constraint.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

    <ImageView android:layout_width="match_parent"
               android:layout_height="0dp"
               android:scaleType="centerCrop"
               android:src="@drawable/you_image"                       
               app:layout_constraintDimensionRatio="1:1"/>


</android.support.constraint.ConstraintLayout>


以下是关于如何将tutorial添加到项目中的ConstraintLayout

答案 7 :(得分:3)

要将ImageView设置为等于屏幕的一半,您需要将以下内容添加到ImageView的XML中:

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:scaleType="fitXY"
    android:adjustViewBounds="true"/>

然后要将高度设置为等于此宽度,您需要在代码中执行此操作。在getView适配器的GridView方法中,将ImageView高度设置为等于其测量宽度:

mImageView.getLayoutParams().height = mImageView.getMeasuredWidth();

答案 8 :(得分:2)

对于过去的人来说,2017年,实现目标的最佳方式是使用ConstraintLayout这样:

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:scaleType="centerCrop"
    app:layout_constraintDimensionRatio="1:1" />

不要忘记根据布局的需要为所有四个方向添加约束。

Build a Responsive UI with ConstraintLayout

此外,到目前为止,PercentRelativeLayout已被弃用(请参阅Android documentation)。

答案 9 :(得分:1)

以下是我解决这个问题的方法:

int pHeight =  picture.getHeight();
int pWidth = picture.getWidth();
int vWidth = preview.getWidth();
preview.getLayoutParams().height = (int)(vWidth*((double)pHeight/pWidth));

preview - imageView的宽度设置为“match_parent”,scaleType设置为“cropCenter”

picture - 要在imageView src中设置的位图对象。

这对我来说非常好。

答案 10 :(得分:0)

我认为你没有办法在XML布局文件中做到这一点,我认为android:scaleType属性不会像你想要的那样工作。
唯一的方法是以编程方式进行。您可以将宽度设置为fill_parent,并可以将屏幕宽度设为View的高度,也可以使用View.getWidth()方法。

答案 11 :(得分:0)

ImageView“scaleType”功能可以为您提供帮助。

此代码将保持纵横比并将图像置于顶部:

android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitStart"

这是一篇很棒的文章,展示了使用scaleType的可能性和外观。

ImageView scaleType samples

答案 12 :(得分:0)

如果图像视图位于约束布局内,则可以使用以下约束来创建正方形图像视图

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/ivImageView"
    app:layout_constraintDimensionRatio="W,1:1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"/>

答案 13 :(得分:0)

我确实是这样-

layout.setMinimumHeight(layout.getWidth());