我有一个ImageView,我希望它的宽度填满父容器。我希望其高度与最终的宽度相同。例如:
<ImageView
android:layout_width="fill_parent"
android:layout_height="whatever the width ends up being" />
在不创建自定义视图类的情况下,是否可以在布局文件中实现这样的操作?
谢谢
我有一个ImageView,我希望它的宽度填满父容器。我希望其高度与最终的宽度相同。例如:
<ImageView
android:layout_width="fill_parent"
android:layout_height="whatever the width ends up being" />
在不创建自定义视图类的情况下,是否可以在布局文件中实现这样的操作?
谢谢
2021年7月28日更新,使用AndroidX而不是支持库
首先,请按照这里的说明导入AndroidX到您的项目中。
然后将您的图像包装在ConstraintLayout
内,并设置其字段如下:
<androidx.constraintlayout.widget.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" />
</androidx.constraintlayout.widget.ConstraintLayout>
请在这里查看
也许这能回答你的问题:
<ImageView
android:id="@+id/cover_image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true" />
对于这种情况,您可以忽略scaleType
属性。
可以使用LayoutParams来动态设置View的高度,一旦您在运行时了解了View的宽度。您需要使用一个Runnable线程来获取运行时视图的宽度,否则您将尝试在了解视图宽度之前设置高度,因为布局尚未绘制。
以下是我解决问题的示例:
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 线程不同的线程上重新绘制。
onMeasure
期间,如 Regis' answer 中所示。另一种方法,但仅适用于通过适配器呈现的视图,例如 GridView
内部的视图,是 Matt's answer。 - ToolmakerSteverequestLayout()
才对我起作用了。这是为什么呢? - Divins Mathew我无法使David Chu的答案在RecyclerView项目中工作,并且发现我需要将ImageView约束到其父视图。将ImageView宽度设置为0dp
,并将其开始和结束约束到父视图。我不确定在某些情况下是否将宽度设置为wrap_content
或match_parent
会起作用,但我认为这是获取ConstraintLayout的子项填充其父项的更好方法。
<androidx.constraintlayout.widget.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"/>
</androidx.constraintlayout.widget.ConstraintLayout>
如果您的图像视图在一个约束布局中,您可以使用以下约束条件创建一个正方形的图像视图,请确保使用1:1来创建正方形
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/ivImageView"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
下面是我为了获得一个始终宽度等于高度的ImageButton而做的事情(并避免在一个方向上出现愚蠢的空白边距......我认为这是SDK的一个错误):
我定义了一个SquareImageButton类,它继承自ImageButton:
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"
/>
运作得非常好!
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>
这里是一份关于如何将ConstraintLayout
添加到您的项目中的教程。
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:scaleType="fitXY"
android:adjustViewBounds="true"/>
要将高度设置为宽度大小,您需要在代码中进行设置。在您的GridView
适配器的getView
方法中,将ImageView
的高度设置为其测量宽度:
mImageView.getLayoutParams().height = mImageView.getMeasuredWidth();
现在对于路过的人,在2017年,实现你想要的最佳方式是像这样使用ConstraintLayout:
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:1" />
不要忘记根据您的布局需要为所有四个方向添加约束。
此外,现在已经弃用了PercentRelativeLayout(请参见Android文档)。