Androidで ImageViewが表示できなくて困った

すっごく基本的なことだと思うのだけど、誰も同様のことを Webで書いていないので自分が何かやらかしているのだと思う…。


困った件はこんな感じ。

画面にスプラッシュスクリーンを表示するのに、画面の横幅に対してロゴは真ん中 80%のサイズで表示したい!って状態。
これ、画面サイズがたっくさんある Androidだと面倒〜。
というわけで、今までは大抵の Android機の画面サイズより大きめの画像を用意しておいて、layout.xml でヨロシク縮小して表示していた。

ところが、eclipseの Project Build Target で Google APIs 2.2 を選択していた時は問題なく表示されていたのだけど、これを Google APIs 4.2.2 にしたらロゴが表示されなくなってしまった…。(もちろん Android 4.2.2 でもダメ)


というわけで、結局そのままのやり方で解決はしなかったので、コードで縮小してなんとかしたのでメモ。
誰か xml だけでなんとかなる方法を知っていたら教えて!

今まで表示に使っていたコード

今までは StackOverflowで見つけたこんなコードで動いていた。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/splashRelativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="horizontal" >

        <LinearLayout android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:id="@+id/linearLayout_dummy1"
            android:layout_weight=".10">
        </LinearLayout>
        <ImageView
            android:id="@+id/listViewSplashImage"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight=".80"
            android:contentDescription="@string/splash_image"
            android:scaleType="centerInside"
            android:src="@drawable/splash_image" />
        <LinearLayout android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:id="@+id/linearLayout_dummy2"
            android:layout_weight=".10">
        </LinearLayout>

    </LinearLayout>

</RelativeLayout>

LinerLayoutで layout_weight使って 0.1/0.8/0.1と並べる方法。
eclipseの画面エディタ?でもちゃんと表示されてる。

けど、実機で見るとバックグラウンドだけでロゴが表示されない〜。

画面の横幅より大きな画像は表示されない?

実は、入り組んだレイアウトでなく、単純にこんなレイアウトにしても画像は表示されない。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/listViewSplashImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:contentDescription="@string/splash_image"
        android:scaleType="centerInside"
        android:src="@drawable/splash_image" />

</RelativeLayout>

もうどうして良いのかわからない…。


で、あれこれやってたら、表示しようとする画像の横幅が画面のサイズより小さいと表示できることを発見。


え〜?
本当にそれが原因なのかな〜?
そんなんが原因なら Webで情報が見つかりそうだけど…。
(画像サイズが大き過ぎてメモリエラーが起きてるとかかな?)


そんなわけで、今回は根本的に画像を表示できなかったので xmlだけでやるのは諦めた!

画面幅の 80%の画像をコードで作った!

結局はコードで画像を画面幅の 80%に縮小して ImageView#setImageBitmap で表示するようにした。

layout.xml はこんな感じ。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/listViewSplashImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:contentDescription="@string/splash_image"
        android:scaleType="centerInside"
        android:src="@drawable/splash_image" />

</RelativeLayout>

真ん中に画像を表示してるだけ。
80%だなんだは関係なし。


で、コードの方はこんな感じ。

Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.splash_image);
Bitmap b2 = resizeBitmapToDisplaySize(this, b, (float) 0.8);
ImageView iv = (ImageView) findViewById(R.id.listViewSplashImage);
iv.setImageBitmap(b2);

Bitmap resizeBitmapToDisplaySize(Activity activity, Bitmap src, float ratio) {
    int srcWidth = src.getWidth();
    int srcHeight = src.getHeight();
 
    Matrix matrix = new Matrix();
    DisplayMetrics metrics = new DisplayMetrics();
    activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
    float screenWidth = (float) metrics.widthPixels;
    float screenHeight = (float) metrics.heightPixels;

    float targetWidth = screenWidth * ratio;

    float widthScale = targetWidth / srcWidth;
    matrix.postScale(widthScale, widthScale);

    Bitmap dst = Bitmap.createBitmap(src, 0, 0, srcWidth, srcHeight, matrix, true);

    src = null;
    return dst;
}

画像をリサイズするコードは、ここから拝借してちょっと変更した。

というわけで、無事スプラッシュスクリーンは横幅 80%のサイズでロゴが表示されることになったのだけど、なんで 2.2 の頃は大丈夫だったものが 4.2.2 でダメになったんだろう…?