可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The src
should stretch its width to match_parent
, while keeping aspect ratio. When the image is larger than the parent, it scales down correctly. But when the image is smaller, it does not scale up. (illustration shows desired behavior).
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:src="@drawable/foo"
/>
</RelativeLayout>
Using ScaleType.fitXY
stretches the width
only
回答1:
I believe that is not possible, at least not with the options provided by scaleType
attribute.
Your best option in this case is to use centerCrop
, but only the center of the picture will be visible.
However, if you are not ok with this option, then you could scale the image programatically without loosing aspect ratio.
In order to achieve this you'll need to calculate a scale factor based on the screen width, and then use this scale factor to know the new height of the image.
Like this:
ImageView imageView = (ImageView)findViewById(R.id.imageView);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.foo);
int imageWidth = bitmap.getWidth();
int imageHeight = bitmap.getHeight();
int newWidth = getScreenWidth(); //this method should return the width of device screen.
float scaleFactor = (float)newWidth/(float)imageWidth;
int newHeight = (int)(imageHeight * scaleFactor);
bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
imageView.setImageBitmap(bitmap);
Also, you'll need to adjust the declaration of ImageView
in layout file:
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
回答2:
android:adjustViewBounds="true"
does the job!
回答3:
setContentView(R.layout.activity_main);
ImageView imageView = (ImageView)findViewById(R.id.imageView);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
int imageWidth = bitmap.getWidth();
int imageHeight = bitmap.getHeight();
DisplayMetrics metrics = this.getResources().getDisplayMetrics();
int newWidth = metrics.widthPixels;
float scaleFactor = (float)newWidth/(float)imageWidth;
int newHeight = (int)(imageHeight * scaleFactor);
bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
imageView.setImageBitmap(bitmap);
LAYOUT
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="@drawable/image" />
回答4:
use this MainImage.setScaleType(ImageView.ScaleType.FIT_XY);
OR you can simply add android:scaleType="fitXY"
in xml.
回答5:
I usually use the following class in XML when I want this behavior:
Of course I tweak it sometimes according to some requirements. But I find it easier to change the class from ImageView to a different class in XML instead of java code in the context of the view.
package shush.android.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* @author Sherif elKhatib
*
* ImageView Class that maintains the width of the view and changes height to keep the aspect ratio.
*/
public class AspectImageView extends ImageView {
public AspectImageView(Context context) {
super(context);
}
public AspectImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AspectImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(getBackground() == null || getBackground().getIntrinsicHeight()==0 || getBackground().getIntrinsicWidth()==0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width * getBackground().getIntrinsicHeight() / getBackground().getIntrinsicWidth();
setMeasuredDimension(width, height);
}
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
@Override
public void setImageBitmap(Bitmap bm) {
if(bm == null)
return;
BitmapDrawable bd = new BitmapDrawable(getContext().getResources(), bm);
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
setBackground(bd);
else
setBackgroundDrawable(bd);
}
}
回答6:
Combining the two brilliant answers (this one and this one) into a quick solution. I hope this saves someone unnecessary research time!
private Bitmap getScaledBitmap(int resource) {
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = displaymetrics.widthPixels;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resource);
float scaleFactor = (float) width / (float) bitmap.getWidth();
int newHeight = (int) (bitmap.getHeight() * scaleFactor);
return Bitmap.createScaledBitmap(bitmap, width, newHeight, true);
}
Use it like this:
imageView.setImageBitmap(getScaledBitmap(R.drawable.banner_home_2));
回答7:
Try android:scaleType="CENTER_INSIDE"
Android docs here
回答8:
Does:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:src="@drawable/foo" />
</RelativeLayout>
Not do what you want?