Answers:
更新: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>
看这里
不推荐使用:
根据Android开发人员的这篇文章,您现在要做的就是将所需的内容包装在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>
也许这会回答您的问题:
<ImageView
android:id="@+id/cover_image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true" />
您可以忽略scaleType此特定情况的属性。
一旦知道运行时的Views宽度,就可以使用LayoutParams动态设置Views的高度。您需要使用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线程不同的单独线程上重绘
onMeasure,如瑞吉斯的回答所示。Matt的答案GridView是一种替代方法,但仅适用于通过适配器(例如在内部)呈现的视图。
requestLayout()在设置参数后调用后才对我有用。为什么会这样呢?
我无法获得David Chu的答案来为RecyclerView项目工作,并且发现我需要将ImageView约束到父对象。将ImageView的宽度设置为,0dp并将其起点和终点约束到父级。我不确定在某些情况下是否将width设置为wrap_content或match_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>
在这里,我做了一个具有始终等于其高度的宽度的ImageButton的操作(并避免在一个方向上出现愚蠢的空白边距...我认为这是SDK的错误...):
我定义了一个从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"
/>
奇迹般有效 !
在Android 26.0.0中,不建议使用PercentRelativeLayout。
解决此问题的最佳方法是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。
我试过了,仅靠布局是无法做到的。我最终编写了一个非常简单的类来处理它,您可以在github上查看它。SquareImage.java它是一个较大项目的一部分,但一点点复制和粘贴都无法解决(在Apache 2.0下获得许可)
本质上,您只需要将高度/宽度设置为等于其他尺寸(取决于您要缩放的方式)
注意:您可以使用scaleType属性将其设置为正方形,而无需使用自定义类,但视图的边界会超出可见图像的范围,如果在其附近放置其他视图,则会使其成为问题。
要将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();
对于现在过世的人们,在2017年,实现您想要的新的最佳方法是使用ConstraintLayout,如下所示:
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:1" />
并且不要忘记根据布局需要将约束添加到所有四个方向。
此外,到目前为止,PercentRelativeLayout已被弃用(请参阅Android文档)。
这是我解决该问题的方法:
int pHeight = picture.getHeight();
int pWidth = picture.getWidth();
int vWidth = preview.getWidth();
preview.getLayoutParams().height = (int)(vWidth*((double)pHeight/pWidth));
预览-imageView的宽度设置为“ match_parent”,scaleType设置为“ cropCenter”
图片-要在imageView src中设置的位图对象。
对我来说这很好。
= vw*ph/pw而不是更简单= vw。(我认为您这样做是为了保留源图像的长宽比,而不是强制进行正方形预览。)
ImageView的“ scaleType”功能可以在这里为您提供帮助。
此代码将保持宽高比并将图像放置在顶部:
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitStart"
这是一篇很棒的文章,展示了使用scaleType带来的可能性和外观。