84

よく尋ねられますが、答えたことはありません (少なくとも再現可能な方法ではありません)。

ビューよりも小さい画像を含む画像ビューがあります。画像を画面の幅に合わせて拡大縮小し、ImageView の高さを調整して、画像の比例して正しい高さを反映させたいと考えています。

<ImageView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

これにより、イメージは元のサイズ (画面の幅よりも小さい) で中央に配置され、左右に余白ができます。ダメ。

だから私は追加しました

android:adjustViewBounds="true" 

同じ効果、ダメ。追加した

android:scaleType="centerInside"

同じ効果、ダメ。に変更centerInsideしましたfitCenter。同じ効果、ダメ。に変更centerInsideしましたcenterCrop

android:scaleType="centerCrop"

最後に、画像は画面の幅に合わせて拡大/縮小されますが、上下がトリミングされます! だから私はに変更centerCropしましたfitXY

android:scaleType="fitXY"

現在、画像は画面の幅に合わせてスケーリングされていますが、y 軸ではスケーリングされていないため、画像が歪んでいます。

削除android:adjustViewBounds="true"しても効果はありません。android:layout_gravity他の場所で提案されているように、を追加しても効果はありません。

私は他の組み合わせを試しましたが、役に立ちませんでした。だから、誰か知っていますか:

ImageView の XML をどのように設定して、画面の幅を埋め、小さな画像をスケーリングしてビュー全体を埋め、歪みやトリミングなしで画像を縦横比で表示しますか?

編集:私も任意の数値の高さを設定しようとしました。これは設定にのみ影響しcenterCropます。ビューの高さに応じて、画像が垂直方向に歪みます。

4

8 に答える 8

39

私はあなたと同じ問題を抱えていました。30分間さまざまなバリエーションを試した後、この方法で問題を解決しました. 親の幅に調整された柔軟な高さと幅を提供します

<ImageView
            android:id="@+id/imageview_company_logo"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:adjustViewBounds="true"
            android:scaleType="fitCenter"
            android:src="@drawable/appicon" />
于 2015-03-07T15:49:18.243 に答える
24

XML レイアウト標準内に実行可能なソリューションはありません。

動的な画像サイズに反応する唯一の信頼できる方法はLayoutParams、コードで使用することです。

残念です。

于 2012-12-24T14:37:34.870 に答える
9
  android:scaleType="fitCenter"

元の src の縦横比を維持しながら、src が dst 内に完全に収まるようにスケールを計算します。少なくとも 1 つの軸 (X または Y) が正確に適合します。結果は dst の中央に配置されます。

編集:

ここでの問題は、layout_height="wrap_content"が画像の拡大を「許可」していないことです。その変更のために、サイズを設定する必要があります

  android:layout_height="wrap_content"

  android:layout_height="100dp"  // or whatever size you want it to be

編集2:

正常に動作します:

<ImageView
    android:id="@+id/imageView1"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    android:scaleType="fitCenter"
    android:src="@drawable/img715945m" />
于 2012-12-21T15:30:54.697 に答える
8

これは、Mark Martinsson の優れたソリューションへの小さな追加です。

画像の幅が高さよりも大きい場合、マークのソリューションは画面の上下にスペースを残します。

以下は、最初に幅と高さを比較することでこれを修正します: 画像の幅が高さ >= の場合、画面の高さに合わせて高さをスケーリングし、次に縦横比を維持するために幅をスケーリングします。同様に、画像の高さ > 幅の場合、画面の幅に合わせて幅をスケーリングし、縦横比を維持するために高さをスケーリングします。

つまり、次の定義を適切に満たしますscaleType="centerCrop"

http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

画像の両方の寸法 (幅と高さ)がビューの対応する寸法 (パディングを引いたもの)以上 なるように、画像を均一にスケーリングします (画像の縦横比を維持し ます)。

package com.mypackage;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class FixedCenterCrop extends ImageView
{
    public FixedCenterCrop(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
    {
        final Drawable d = this.getDrawable();

        if(d != null) {
            int height = MeasureSpec.getSize(heightMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);

            if(width >= height)
                height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
            else
                width = (int) Math.ceil(height * (float) d.getIntrinsicWidth() / d.getIntrinsicHeight());

            this.setMeasuredDimension(width, height);

        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

このソリューションは、縦向きまたは横向きモードで自動的に機能します。マークのソリューションと同じように、レイアウトで参照します。例えば:

<com.mypackage.FixedCenterCrop
    android:id="@+id/imgLoginBackground"
    android:src="@drawable/mybackground"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:scaleType="centerCrop" />
于 2014-07-29T06:49:50.737 に答える
0

Mark Matinsson のソリューションにもう 1 つ追加します。一部の画像が他の画像よりも拡大縮小されていることがわかりました。そのため、画像が最大倍率でスケーリングされるようにクラスを変更しました。画像が小さすぎてぼやけずに最大幅でスケーリングできない場合、最大制限を超えたスケーリングは停止します。

public class DynamicImageView extends ImageView {

    final int MAX_SCALE_FACTOR = 2;
    public DynamicImageView(final Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        final Drawable d = this.getDrawable();

        if (d != null) {
            // ceil not round - avoid thin vertical gaps along the left/right edges
            int width = View.MeasureSpec.getSize(widthMeasureSpec);
            if (width > (d.getIntrinsicWidth()*MAX_SCALE_FACTOR)) width = d.getIntrinsicWidth()*MAX_SCALE_FACTOR;
            final int height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
            this.setMeasuredDimension(width, height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}
于 2015-10-16T16:12:31.417 に答える