私は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を取得してBitmap
に画像をロードします
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="fill_parent"
Android:layout_height="wrap_content"
Android:adjustViewBounds="true"
Android:scaleType="fitCenter" />
scaleType="fitCenter"
(省略時のデフォルト)
scaleType="centerInside"
src
の固有の幅が親の幅より小さい場合src
の固有の幅が親の幅よりも大きい場合Android:src
またはImageView.setImage*
メソッドを使用するかどうかは問題ではなく、おそらくキーはadjustViewBounds
です。
私はarnefmの答えが好きですが、彼は私が訂正しようとする小さなミスをしました(コメントを見てください):
import Android.content.Context;
import Android.graphics.drawable.Drawable;
import Android.util.AttributeSet;
import Android.widget.ImageView;
/**
* ImageView that keeps aspect ratio when scaled
*/
public class ScaleImageView extends ImageView {
public ScaleImageView(Context context) {
super(context);
}
public ScaleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScaleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
Drawable drawable = getDrawable();
if (drawable == null) {
setMeasuredDimension(0, 0);
} else {
int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
if (measuredHeight == 0 && measuredWidth == 0) { //Height and width set to wrap_content
setMeasuredDimension(measuredWidth, measuredHeight);
} else if (measuredHeight == 0) { //Height set to wrap_content
int width = measuredWidth;
int height = width * drawable.getIntrinsicHeight() / drawable.getIntrinsicWidth();
setMeasuredDimension(width, height);
} else if (measuredWidth == 0){ //Width set to wrap_content
int height = measuredHeight;
int width = height * drawable.getIntrinsicWidth() / drawable.getIntrinsicHeight();
setMeasuredDimension(width, height);
} else { //Width and height are explicitly set (either to match_parent or to exact value)
setMeasuredDimension(measuredWidth, measuredHeight);
}
}
} catch (Exception e) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
したがって、あなたのImageView
は適切に拡大縮小され、(例えば)ScrollView
の中に入れば、次元の問題はありません。
私は一度同様の問題を抱えていた。私はカスタム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);
}
これはアスペクト比を維持しながら画像をスクリーンに合うように引き伸ばします。
Android:scaleType="centerCrop"
を使用してください。
私は上記と同じようなことをしました、そしてそれがRelativeLayout
の中ではうまくいかなかったので数時間の間壁に頭をぶつけました。私は次のようなコードになった。
package com.example;
import Android.content.Context;
import Android.graphics.drawable.Drawable;
import Android.util.AttributeSet;
import Android.widget.ImageView;
public class ScaledImageView extends ImageView {
public ScaledImageView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final Drawable d = getDrawable();
if (d != null) {
int width;
int height;
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
height = MeasureSpec.getSize(heightMeasureSpec);
width = (int) Math.ceil(height * (float) d.getIntrinsicWidth() / d.getIntrinsicHeight());
} else {
width = MeasureSpec.getSize(widthMeasureSpec);
height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
}
setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
そしてRelativeLayout
が測定された寸法を無視しないようにするために、私はこれをしました:
<FrameLayout
Android:id="@+id/image_frame"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentLeft="true"
Android:layout_below="@+id/something">
<com.example.ScaledImageView
Android:id="@+id/image"
Android:layout_width="wrap_content"
Android:layout_height="150dp"/>
</FrameLayout>
ImageViewで背景として画像を設定する場合、これは適用されません、srcに設定する必要があります(Android:src)。
ありがとう。
これを試してください:それは私のための問題を解決しました
Android:adjustViewBounds="true"
Android:scaleType="fitXY"
Javaコードは必要ありません。あなたがする必要があります:
<ImageView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:adjustViewBounds="true"
Android:scaleType="centerCrop" />
幅と高さの一致する親にキーがあります
縦横比を維持するためにImageViewでこれらのプロパティを使います:
Android:adjustViewBounds="true"
Android:scaleType="fitXY"
あなたは手動で画像をロードすることによってあなたがしていることを試みることができます、しかし私は非常に非常に強く Universal Image Loader を見ることを勧めます。
私は最近それを私のプロジェクトに統合しました、そしてそれは素晴らしいと言わなければなりません。非同期化、サイズ変更、画像のキャッシュを心配していませんか。統合とセットアップは本当に簡単です。 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のサイズに正しく合わせることができます。
- この現在の設定は画像の縦横比を保持しているので、元の質問にも当てはまります。
幅が画面の幅と等しく、縦横比に応じて高さが比例して設定された画像を作成するには、次の手順を実行します。
Glide.with(context).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
// creating the image that maintain aspect ratio with width of image is set to screenwidth.
int width = imageView.getMeasuredWidth();
int diw = resource.getWidth();
if (diw > 0) {
int height = 0;
height = width * resource.getHeight() / diw;
resource = Bitmap.createScaledBitmap(resource, width, height, false);
}
imageView.setImageBitmap(resource);
}
});
お役に立てれば。
この単純な行を試してみてください...依存関係を追加することなく、画像表示タグのxmlコードにこの行を追加します。Android:scaleType = "fitXY"
UniversalImageLoaderを使用して設定するだけです。
DisplayImageOptions.Builder()
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
.build();
とImageViewのスケール設定なし
使いやすいピカソを使用してください。
あなたのアダプタで..
@Override
public void getView(int position, View convertView, ViewGroup parent) {
ImageView view = (ImageView) convertView.findViewById(R.id.ranking_prod_pic);
Picasso.with(context).load(url).into(view); //url is image url
//you can resize image if you want
/* Picasso.with(context) .load(url) .resize(50, 50) .centerCrop() .into(view) */
}
androidを使用:ScaleType = "fitXY" im ImageView xml