0

私のアプリには、垂直方向にスクロールする ImageButtons のリストを表示するアクティビティがあります。各ボタンの画像を (A) アセット フォルダーから取得し、(B) スケーリングしても縦横比を維持するようにします。残念ながら、イメージがアセット フォルダーから取得された場合、ImageButton のサイズが正しくありません。

ドローアブルから設定された ImageButton src

最初のスクリーンショットは、すべての画像がアプリのドローアブルから取得されるテスト アプリです。それがその画像の「正しい」縦横比であり、これを維持したいのです (すべての画像ボタンには scaleType "fitXY" "centerCrop" が与えられています)。

ドローアブルから取得した画像

アセットから設定された ImageButton src

2 番目のスクリーンショットは、すべての画像がアプリの "assets" フォルダーから取得されたテスト アプリです。ご覧のとおり、画像は必要に応じて画面の幅いっぱいに引き伸ばされていますが、元の縦横比は失われています。

アセットから取得した画像

アクティビティ コード (MainActivity.java)

LinearLayout buttons = (LinearLayout) findViewById(R.id.buttons);
View button = layoutInflater.inflate(R.layout.snippet_imagebutton, null);
ImageButton imageButton = (ImageButton) button.findViewById(R.id.imageButton);
if (GET_IMAGE_FROM_ASSETS) {
    InputStream s = assetManager.open("image.png");
    Bitmap bmp = BitmapFactory.decodeStream(s);
    imageButton.setImageBitmap(bmp);
} else {
    imageButton.setImageResource(R.drawable.image);
}
TextView buttonText = (TextView) button.findViewById(R.id.textView);
buttonText.setText("Button text!");
buttons.addView(button,
    new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

ボタンのレイアウト (snippet_imagebutton.xml)

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp">
    <ImageButton
        android:id="@+id/imageButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />
    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:gravity="center"
        android:textColor="#FFF"
        android:background="#88000000"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>

危険なハック

私が望むものを実現し、問題を説明する危険なハックを見つけました — ImageButton は、リソースから拡大された画像に一致するように正しくサイズ設定されますが、アセットから拡大された画像に一致するように正しくサイズ変更されません。もしあれば、危険なハックよりも「本物の」ソリューションを好むでしょう。:)

// to start with, scale the ImageButton based on an image in our
// resources that has the same dimensions as the image in our assets
imageButton.setImageResource(R.drawable.image);
// when we eventually render (we don't have width / height yet)...
imageButton.post(new Runnable() {
    public void run() {
        int height = imageButton.getHeight();
        int width = imageButton.getWidth();
        // replace our "resource" image with our "asset" image
        imageButton.setImageBitmap(bmp);
        // and force the ImageButton to keep the same scale as previously
        imageButton.setLayoutParams(
            new RelativeLayout.LayoutParams(width, height));
    }
});

概要

アプリの「資産」フォルダーからこれらのボタンの画像を取得したいと考えています。ボタン画像がすべて適切にスケーリングされるように (つまり、元の縦横比を維持するように) アプリを修正するにはどうすればよいですか?

これは、フレームワークが ImageButton を画面にレンダリングする前に、実際には画像の幅/高さを認識していないことに関係していると思います。どうすれば修正できますか? RelativeLayoutとImageButton自体の両方でadjustViewBoundsを「true」に設定しようとしましたが、効果がないようでした。

4

2 に答える 2

2

スケール タイプ属性を「fitXY」として指定すると、縦横比は保持されません。必要に応じて、「center」、「center_crop」、または「center_inside」を試してください。ImageViewScaleTypeも確認してください。

于 2013-02-19T09:27:48.290 に答える
1

私が収集したものから、AdjustViewBounds は実際に必要な機能を正確に提供するメソッドです。ただし、Roman Nurik がここで説明しているように、AdjustViewBounds は、ドローアブルの自然な寸法を超えて ViewBounds を増やしません。

リソース/アセットをどのように割り当てたかを確認せずに、リソースからロードするときとアセットからロードするときに違いが見られるのはこのためではないかと思います。リソース ファイルは、おそらく、ロード時に拡大されているため (これがリソースのデフォルトの動作であるため)、/res から返されるドローアブルの実際のサイズは、/assets からデコードしたビットマップよりも大幅に大きくなります。

ImageButton をオーバーライドする (Nurik が示唆するように) ことはもちろん 1 つのオプションですが、おそらくやり過ぎです。

問題について私が正しいと仮定すると、Assets ファイルをロードするときに BitmapFactory.options を正しく設定するだけで問題を解決できるはずです。デバイスに応じて inDensity と inTargetDensity を正しく設定し (DisplayMetrics を取得)、inScaled を true に設定する必要があります。

または、ビットマップを ImageButton にロードする前に、手動でいつでも再スケーリングできます。画面の幅をつかむだけで、どのくらいの大きさにする必要があるかを判断できます。

PS

自動スケーリングは明らかに洗練されたソリューションですが、弱点があります (リソースとアセットの両方に等しく適用されます) - ディスプレイの幅 > スケールアップ時のビットマップ幅の場合、アスペクト比が台無しになる可能性があります。 . これは、ランドスケープ モードに切り替えて、リソース ファイルのアスペクト比が正しいかどうかを確認することで、非常に簡単に確認できます。十分な大きさのベース イメージがある場合 (または、画面のサイズ/向きに応じて異なるレイアウトを使用する場合)、これは問題になりません。心に留めておくべきことがあります。

于 2013-02-28T10:57:27.937 に答える