web-dev-qa-db-ja.com

Android ImageViewは親の高さとフィッティング幅を調整します

Updatethis answer で説明されている方法を使用してこの問題を解決しました

私はこの問題に少しこだわっていますが、これは非常に簡単なはずです。

私のアプリは画像をダウンロードし、RelativeLayoutの子要素であるImageViewにビットマップをレンダリングします。 ImageViewを親の幅に合わせ、そのサイズを調整してアスペクト比を維持したいと思います。

これが私のXMLです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
>
<RelativeLayout Android:id="@+id/banner" Android:layout_width="fill_parent" Android:layout_height="wrap_content"></RelativeLayout>
<TextView  
Android:layout_width="fill_parent" 
Android:layout_height="wrap_content" 
Android:text="@string/hello"
/>
</LinearLayout>

そしてコード:

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    RelativeLayout banner = (RelativeLayout) findViewById(R.id.banner);
    ImageView imgV = new ImageView(this);

    imgV.setScaleType(ImageView.ScaleType.CENTER_CROP);
    // I tried all the scale types : CENTER_INSIDE : same effect, FIT_CENTER : same effect... 

    imgV.setBackgroundColor(0x00FFFF00);

    imgV.setAdjustViewBounds(Color.BLUE);


    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

    banner.addView(imgV,params);

    // Some code downloading the image stream

    bitmap = BitmapFactory.decodeStream(stream);


    imgV.setImageBitmap(bitmap);

    }

望ましい:

Desired result

結果:

Current result

62
Julien

@Julienと@jsに感謝します。ビットマップがImageViewよりも小さい場合でも、アスペクト比を維持したままビットマップの高さを引き伸ばすImageViewの完全なソリューションを次に示します。

public class ResizableImageView extends ImageView {

    public ResizableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

         if(d!=null){
                 // ceil not round - avoid thin vertical gaps along the left/right edges
                 int width = MeasureSpec.getSize(widthMeasureSpec);
                 int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
                 setMeasuredDimension(width, height);
         }else{
                 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         }
    }

}

ImageViewの代わりに、XMLレイアウトでこのクラスを使用できます。

<com.example.ResizableImageView
    Android:id="@+id/banner"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:src="@drawable/banner" />
146
Serafim Suhenky

おそらくXMLで_Android:adjustViewBounds="true"_を、JavaでimageView.setAdjustViewBounds(true)を探しているでしょう。

51
Matthew Willis

コメントで述べたように、ImageViewをサブクラス化しました。私のコードを見つけました、ここに行きます:

    protected class ResizableImageView extends ImageView
    {

        private Bitmap mBitmap;

        // Constructor

        public ResizableImageView(Context context)
        {
            super(context);
        }


        // Overriden methods


          @Override 
          protected void onMeasure(int widthMeasureSpec,
                  int heightMeasureSpec) {
              if(mBitmap != null)
              {
                    int width = MeasureSpec.getSize(widthMeasureSpec);
                    int height = width * mBitmap.getHeight() / mBitmap.getWidth();
                    setMeasuredDimension(width, height);

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

            @Override
            public void setImageBitmap(Bitmap bitmap)
            {
                mBitmap = bitmap;
                 super.setImageBitmap(bitmap);
            }

    }
8
Julien

@Seraphim Sのソリューションにわずかな変更を加えて、画像が広く、ビューの境界も広い場合を考慮しました(たとえば、デバイスを横長モードに回転させる)。

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

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

        if (d != null) {

            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);

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

            setMeasuredDimension(width, height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}
2
chuz

ImgVの幅を「match_parent」に変更する必要があると思います

スケールタイプをimgV.setScaleType(ImageView.ScaleType.CENTER_INSIDE);に変更する必要があります。

2
2bard