我有一个GridView。GridView的数据是来自服务器的请求。
下面是GridView中的项目布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/analysis_micon_bg"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/half_activity_vertical_margin"
android:paddingLeft="@dimen/half_activity_horizontal_margin"
android:paddingRight="@dimen/half_activity_horizontal_margin"
android:paddingTop="@dimen/half_activity_vertical_margin" >
<ImageView
android:id="@+id/ranking_prod_pic"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/ranking_rank_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/ranking_prod_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/ranking_prod_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
我从服务器请求数据,获取图像url和加载图像到位图
public static Bitmap loadBitmapFromInputStream(InputStream is) {
return BitmapFactory.decodeStream(is);
}
public static Bitmap loadBitmapFromHttpUrl(String url) {
try {
return loadBitmapFromInputStream((InputStream) (new URL(url).getContent()));
} catch (Exception e) {
Log.e(TAG, e.getMessage());
return null;
}
}
适配器中有getView(int position, View convertView, ViewGroup parent)方法的代码
Bitmap bitmap = BitmapUtil.loadBitmapFromHttpUrl(product.getHttpUrl());
prodImg.setImageBitmap(bitmap);
图像大小为210*210。我在Nexus 4上运行我的应用程序。图像填充ImageView的宽度,但ImageView的高度没有缩放。ImageView不显示整个图像。
我怎么解决这个问题?
不使用任何自定义类或库:
<ImageView
android:id="@id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
scaleType="fitCenter"(省略时默认值)
将使它的宽度作为父允许和上升/下降规模,需要保持纵横比。
scaleType = centerInside”
如果SRC的固有宽度小于父宽度,则将图像水平居中
如果SRC的固有宽度大于父宽,将使其宽到父宽所允许的范围,并降低比例保持纵横比。
不管你使用android:src还是ImageView。setImage*方法,键可能是adjustViewBounds。
你可以尝试手动加载图像,但我强烈建议你看一下通用图像加载器。
我最近把它整合到我的项目中,我不得不说它太棒了。这些都是异步的,调整大小,缓存图像。它真的很容易集成和设置。在5分钟内你就可以让它按你想要的做。
示例代码:
//ImageLoader config
DisplayImageOptions displayimageOptions = new DisplayImageOptions.Builder().showStubImage(R.drawable.downloadplaceholder).cacheInMemory().cacheOnDisc().showImageOnFail(R.drawable.loading).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).
defaultDisplayImageOptions(displayimageOptions).memoryCache(new WeakMemoryCache()).discCache(new UnlimitedDiscCache(cacheDir)).build();
if (ImageLoader.getInstance().isInited()) {
ImageLoader.getInstance().destroy();
}
ImageLoader.getInstance().init(config);
imageLoadingListener = new ImageLoadingListener() {
@Override
public void onLoadingStarted(String s, View view) {
}
@Override
public void onLoadingFailed(String s, View view, FailReason failReason) {
ImageView imageView = (ImageView) view;
imageView.setImageResource(R.drawable.android);
Log.i("Failed to Load " + s, failReason.toString());
}
@Override
public void onLoadingComplete(String s, View view, Bitmap bitmap) {
}
@Override
public void onLoadingCancelled(String s, View view) {
}
};
//Imageloader usage
ImageView imageView = new ImageView(getApplicationContext());
if (orientation == 1) {
imageView.setLayoutParams(new LinearLayout.LayoutParams(width / 6, width / 6));
} else {
imageView.setLayoutParams(new LinearLayout.LayoutParams(height / 6, height / 6));
}
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageLoader.displayImage(SERVER_HOSTNAME + "demos" + demo.getPathRoot() + demo.getRootName() + ".png", imageView, imageLoadingListener);
这可以延迟加载图像,使它们正确地适应imageView的大小,在加载时显示占位符图像,并在加载失败时显示默认图标并缓存资源。
我还应该补充一下,当前的配置保持了图像的纵横比,因此适用于你最初的问题
我有一个类似的问题,我发现这是因为你需要计算dp。Android studio会在你从drawable加载时计算ImageView,但当你使用另一种方法时,比如从bitmap加载dp不会自动计入,
这是我的xml
<ImageView
android:id="@+id/imageViewer"
android:layout_width="match_parent"
android:layout_height="match_parent"//dp is not automaticly updated, when loading from a other source
android:scaleType="fitCenter"
tools:srcCompat="@drawable/a8" />
我使用Kotlin,并从资产文件加载可绘制的,这是我如何计算这一点
val d = Drawable.createFromStream(assets.open("imageData/${imageName}.png"), null)
bitHeight = d.minimumHeight//get the image height
imageViewer.layoutParams.height = (bitHeight * resources.displayMetrics.density).toInt()//set the height
imageViewer.setImageDrawable(d)//set the image from the drawable
imageViewer.requestLayout()//here I apply it to the layout
我曾经遇到过类似的问题。我通过制作一个自定义ImageView解决了这个问题。
public class CustomImageView extends ImageView
然后重写imageview的onMeasure方法。我相信我做过这样的事情:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
Drawable drawable = getDrawable();
if (drawable == null) {
setMeasuredDimension(0, 0);
} else {
float imageSideRatio = (float)drawable.getIntrinsicWidth() / (float)drawable.getIntrinsicHeight();
float viewSideRatio = (float)MeasureSpec.getSize(widthMeasureSpec) / (float)MeasureSpec.getSize(heightMeasureSpec);
if (imageSideRatio >= viewSideRatio) {
// Image is wider than the display (ratio)
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = (int)(width / imageSideRatio);
setMeasuredDimension(width, height);
} else {
// Image is taller than the display (ratio)
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = (int)(height * imageSideRatio);
setMeasuredDimension(width, height);
}
}
} catch (Exception e) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
这将拉伸图像以适应屏幕,同时保持纵横比。