Mun*_*ndi 77 android imageview image-scaling
经常被问到,从来没有回答过(至少不是以可重复的方式).
我有一个图像视图,其图像小于视图.我想将图像缩放到屏幕的宽度,并调整ImageView的高度以反映图像的比例正确高度.
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Run Code Online (Sandbox Code Playgroud)
这导致图像以其原始尺寸(小于屏幕宽度)为中心,边缘为边缘.不好.
所以我补充道
android:adjustViewBounds="true"
Run Code Online (Sandbox Code Playgroud)
同样的效果,没有好处.我补充道
android:scaleType="centerInside"
Run Code Online (Sandbox Code Playgroud)
同样的效果,没有好处.我换centerInside了fitCenter.同样的效果,没有好处.我换centerInside了centerCrop.
android:scaleType="centerCrop"
Run Code Online (Sandbox Code Playgroud)
现在,最后,图像缩放到屏幕的宽度 - 但在顶部和底部裁剪!所以我改变了centerCrop对fitXY.
android:scaleType="fitXY"
Run Code Online (Sandbox Code Playgroud)
现在,图像缩放到屏幕的宽度,但没有在y轴上缩放,导致图像失真.
删除android:adjustViewBounds="true"无效.android:layout_gravity如其他地方所建议的,添加一个也没有效果.
我尝试过其他组合 - 无济于事.所以,请有人知道:
如何设置ImageView的XML来填充屏幕的宽度,缩放较小的图像以填充整个视图,显示具有宽高比的图像而不会失真或裁剪?
编辑:我也尝试设置任意数字高度.这仅对centerCrop设置有影响.它会根据视图高度垂直扭曲图像.
Mar*_*son 110
我通过创建一个包含在layout-file中的java类来解决这个问题:
public class DynamicImageView extends ImageView {
public DynamicImageView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final Drawable d = this.getDrawable();
if (d != null) {
// ceil not round - avoid thin vertical gaps along the left/right edges
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
this.setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您通过将您的类添加到布局文件中来使用它:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<my.package.name.DynamicImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@drawable/about_image" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
小智 34
我和你的问题一样.在尝试不同变化30分钟后,我以这种方式解决了问题.它为您提供灵活的高度,宽度调整为父宽度
<ImageView
android:id="@+id/imageview_company_logo"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/appicon" />
Run Code Online (Sandbox Code Playgroud)
android:scaleType="fitCenter"
Run Code Online (Sandbox Code Playgroud)
计算将保持原始src宽高比的比例,但也将确保src完全适合dst.至少一个轴(X或Y)将完全适合.结果集中在dst内.
编辑:
这里的问题layout_height="wrap_content"是不是"允许"图像扩展.对于该更改,您必须为其设置大小
android:layout_height="wrap_content"
Run Code Online (Sandbox Code Playgroud)
至
android:layout_height="100dp" // or whatever size you want it to be
Run Code Online (Sandbox Code Playgroud)
EDIT2:
工作良好:
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="fitCenter"
android:src="@drawable/img715945m" />
Run Code Online (Sandbox Code Playgroud)
这是Mark Martinsson优秀解决方案的一小部分.
如果图像的宽度大于其高度,那么Mark的解决方案将在屏幕的顶部和底部留出空间.
下面通过首先比较宽度和高度来解决这个问题:如果图像宽度> =高度,那么它将缩放高度以匹配屏幕高度,然后缩放宽度以保持宽高比.同样,如果图像高度>宽度,则它将缩放宽度以匹配屏幕宽度,然后缩放高度以保留纵横比.
换句话说,它恰当地满足了以下定义scaleType="centerCrop":
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
缩放图像均匀(保持图像的纵横比),使得 这两个尺寸(宽度和高度)的图像将是等于或 大于所述视图(负填充)的对应尺寸.
package com.mypackage;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class FixedCenterCrop extends ImageView
{
public FixedCenterCrop(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
{
final Drawable d = this.getDrawable();
if(d != null) {
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
if(width >= height)
height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
else
width = (int) Math.ceil(height * (float) d.getIntrinsicWidth() / d.getIntrinsicHeight());
this.setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
Run Code Online (Sandbox Code Playgroud)
此解决方案自动以纵向或横向模式运行.您可以像在Mark的解决方案中一样在布局中引用它.例如:
<com.mypackage.FixedCenterCrop
android:id="@+id/imgLoginBackground"
android:src="@drawable/mybackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:scaleType="centerCrop" />
Run Code Online (Sandbox Code Playgroud)