ページ

2014/04/22

[Android]ImageViewのScaleTypeと縦横比を維持したままImageViewを拡大縮小する方法

ImageView の ScaleType や adujstViewBounds を設定した場合の挙動って
Layout Editor のビジュアル表示だとわかりにくいですよね。
実機との表示が違ったりして良い感じの表示にできなくて苦戦すること、あると思います。
面倒なので ImageView のパラメータをその場で変更できるアプリを作りました。
色々変更して自分が求めていた組み合わせを見つけて下さい。

wada811/ImageViewScaling

MATRIX: Matrix を使用して拡大縮小する。
FIT_XY: 縦横比を無視して View サイズに合わせて拡大縮小する。
FIT_CENTER: 縦横比を維持したまま View サイズに合わせて拡大縮小する。Gravity.CENTER
FIT_START: 縦横比を維持したまま View サイズに合わせて拡大縮小する。Gravity.TOP
FIT_END: 縦横比を維持したまま View サイズに合わせて拡大縮小する。Gravity.BOTTOM
CENTER: 拡大縮小しない。Gravity.CENTER
CENTER_INSIDE: View サイズに入るように縦横比を維持したまま等倍・縮小する。Gravity.CENTER
CENTER_CROP: View サイズを覆うように縦横比を維持したまま等倍・拡大する。Gravity.CENTER
ImageView.ScaleType | Android Developers
Matrix.ScaleToFit | Android Developers

上記の ScaleType を指定しても View サイズは変わりません。
画像を画面幅に合わせて縦横比を維持したまま拡大して表示したい場合、
以下のように設定することで(図左)のように表示することができます。(水色は ImageView の背景色)
layout_width: match_parent
layout_height: match_parent
ScaleType: FIT_START

しかし、ImageView のサイズが match_parent なので
ImageView を最大サイズで表示して下の余った領域で他の UI パーツを表示することが難しいです。
そこで以下のように記述することで(図右)のように ImageView 自体を拡大して表示することができます。
あとは RelativeLayout で ImageView の下の余った領域で他の UI パーツを表示することができます。
public void fitDisplayInside(Context context, ImageView imageView){
    Bitmap bitmap = BitmapUtils.createBitmapFromDrawable(imageView.getDrawable());
    float factor = (float)DisplayUtils.getWidth(context) / bitmap.getWidth();
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(DisplayUtils.getWidth(context), (int)(bitmap.getHeight() * factor));
    imageView.setLayoutParams(params);
    Matrix matrix = imageView.getImageMatrix();
    matrix.reset();
    matrix.postScale(factor, factor);
    imageView.setImageMatrix(matrix);
}

BitmapUtils#createBitmapFromDrawable wada811/AndroidLibrary-wada811
DisplayUtils#getWidth wada811/AndroidLibrary-wada811

参考: JavaScriptでギャルゲーを作る : 縦横比を維持したまま、ImageViewの拡大縮小を行う方法

追記(2014/04/27): 上の処理をしなくても(図右)のようにできました

layout_width: match_parent
layout_height: wrap_content
ScaleType: FIT_START
adjustViewBounds: true
領域の幅と高さのどちらに合わせるかでどちらが wrap_content か任意の大きさになるかは異なりますが、
上記のように指定すれば高さが画像の比率に合わせて変わるので(図右)のようになります。