Saya baru saja membaca kode sumbernya ImageView
dan pada dasarnya tidak mungkin tanpa menggunakan solusi subclassing di utas ini. Di ImageView.onMeasure
kita sampai ke baris ini:
// Get the max possible width given our constraints
widthSize = resolveAdjustedSize(w + pleft + pright, mMaxWidth, widthMeasureSpec);
// Get the max possible height given our constraints
heightSize = resolveAdjustedSize(h + ptop + pbottom, mMaxHeight, heightMeasureSpec);
Dimana h
dan w
apakah dimensi gambar, dan p*
merupakan paddingnya.
Lalu:
private int resolveAdjustedSize(int desiredSize, int maxSize,
int measureSpec) {
...
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
/* Parent says we can be as big as we want. Just don't be larger
than max size imposed on ourselves.
*/
result = Math.min(desiredSize, maxSize);
Jadi jika sudah layout_height="wrap_content"
akan di atur widthSize = w + pleft + pright
, atau dengan kata lain lebar maksimum sama dengan lebar gambar.
Artinya, kecuali Anda menyetel ukuran yang tepat, gambar TIDAK PERNAH diperbesar . Saya menganggap ini sebagai bug, tapi semoga berhasil membuat Google memperhatikan atau memperbaikinya. Edit: Makan kata-kata saya sendiri, saya serahkan laporan bug dan mereka mengatakan itu telah diperbaiki di rilis mendatang!
Solusi lain
Berikut adalah solusi subclass lain, tetapi Anda harus (secara teori, saya belum benar-benar mengujinya!) Dapat menggunakannya di mana pun Anda ImageView
. Untuk menggunakannya, set layout_width="match_parent"
, dan layout_height="wrap_content"
. Ini jauh lebih umum daripada solusi yang diterima juga. Misalnya Anda bisa melakukan fit-to-height serta fit-to-width.
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
// This works around the issue described here: http://stackoverflow.com/a/12675430/265521
public class StretchyImageView extends ImageView
{
public StretchyImageView(Context context)
{
super(context);
}
public StretchyImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public StretchyImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// Call super() so that resolveUri() is called.
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// If there's no drawable we can just use the result from super.
if (getDrawable() == null)
return;
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int w = getDrawable().getIntrinsicWidth();
int h = getDrawable().getIntrinsicHeight();
if (w <= 0)
w = 1;
if (h <= 0)
h = 1;
// Desired aspect ratio of the view's contents (not including padding)
float desiredAspect = (float) w / (float) h;
// We are allowed to change the view's width
boolean resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
// We are allowed to change the view's height
boolean resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
int pleft = getPaddingLeft();
int pright = getPaddingRight();
int ptop = getPaddingTop();
int pbottom = getPaddingBottom();
// Get the sizes that ImageView decided on.
int widthSize = getMeasuredWidth();
int heightSize = getMeasuredHeight();
if (resizeWidth && !resizeHeight)
{
// Resize the width to the height, maintaining aspect ratio.
int newWidth = (int) (desiredAspect * (heightSize - ptop - pbottom)) + pleft + pright;
setMeasuredDimension(newWidth, heightSize);
}
else if (resizeHeight && !resizeWidth)
{
int newHeight = (int) ((widthSize - pleft - pright) / desiredAspect) + ptop + pbottom;
setMeasuredDimension(widthSize, newHeight);
}
}
}