Android ImageView setting Bitmap FitXY doesn't work

24,325

Solution 1

Using scaleType will not change the size of your ImageView, as you seem to think it should. All it does is scale the bitmap up to the size of the ImageView(which it is doing quite well, judging by your screenshot).

If you want to make square ImageViews, you should try looking at this question.

Also, I'm not sure I understand why you're using the TwoWayGridView library. It's specifically designed to allow you to state the number of rows/columns, and it will stretch the items to fit. This seems to be the exact opposite of what you want, since you want to make them square. A normal GridView will work, provided you override the onMeasure() of each item like it shows in the linked quesion/answer.

Solution 2

I wonder what container widget you use for holding ImageView.
for example... GridView, ListView, etc...
If you use GridView, you try to set count of column by GridView.setNumColumns().

If still does not work, you try to use AspectRatioFrameLayout class by one of many way.
this class is simple. follow the steps below!


1. add attributes in res/attrs.xml

<declare-styleable name="AspectRatioFrameLayout">
    <attr name="aspectRatio" format="float" />
</declare-styleable>


2. create AspectRatioFrameLayout class

public class AspectRatioFrameLayout extends FrameLayout {
    private static final String TAG = "AspectRatioFrameLayout";
    private static final boolean DEBUG = false;

    private float mAspectRatio; // width/height ratio

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

    public AspectRatioFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        initAttributes(context, attrs);
    }

    public AspectRatioFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        initAttributes(context, attrs);
    }

    private void initAttributes(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AspectRatioFrameLayout);

        mAspectRatio = typedArray.getFloat(R.styleable.AspectRatioFrameLayout_aspectRatio, 1.0f);

        typedArray.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if (DEBUG) Log.d(TAG, "widthMode:"+widthMode+", heightMode:"+heightMode);
        if (DEBUG) Log.d(TAG, "widthSize:"+widthSize+", heightSize:"+heightSize);

        if ( widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY ) {
            // do nothing
        } else if ( widthMode == MeasureSpec.EXACTLY ) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec((int)(widthSize / mAspectRatio), MeasureSpec.EXACTLY);
        } else if ( heightMode == MeasureSpec.EXACTLY ) {
            widthMeasureSpec = MeasureSpec.makeMeasureSpec((int)(heightSize * mAspectRatio), MeasureSpec.EXACTLY);
        } else {
            // do nothing
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}


3. modify list_item_image.xml

<your.package.AspectRatioFrameLayout       
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    app:aspectRatio="1">

    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/imageView" 
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:src="@drawable/locked_image"
        android:scaleType="fitXY"
    />
</your.package.AspectRatioFrameLayout>

Solution 3

Instead of using src property, Use background property of imageView. Bitmap will be stretched.

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/imageView" 
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@drawable/locked_image"
android:scaleType="fitXY"
/>
Share:
24,325
idish
Author by

idish

I'm here to improve my knowledge on C#, help the community, and learn some other stuff related to programming.

Updated on August 11, 2020

Comments

  • idish
    idish over 3 years

    I've been trying for a really long time to set the bitmap so it will fit the ImageView bounds.

    It just doesn't work via scaleType: fitXY. My bitmap images size are lower than the ImageView's (Saved on 100X100 pixels), I want my bitmap images to fit and stretch into the ImageView.

    Here's some code:

    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
       android:id="@+id/imageView" 
       android:layout_height="match_parent"
       android:layout_width="match_parent"
       android:src="@drawable/locked_image"
       android:scaleType="fitXY"
    />
    

    Here's the code of setting the ImageView (I'm setting the scaleType in different places for testing):

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      final ImageView imageView;
      if (convertView == null) {
        imageView = (ImageView) getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);
        imageView.setScaleType(ScaleType.FIT_XY);
      } else {
        imageView = (ImageView) convertView;
        imageView.setScaleType(ScaleType.FIT_XY);
      }
    
      imageLoader.displayImage(imagesIds[position], imageView, options);
      imageView.setScaleType(ScaleType.FIT_XY);
      return imageView;
    }
    

    Here's how it looks:

    enter image description here

    As you can see, the Height of the ImageView is fine, but I want the Width of it to be the same. I do not have access to my bitmap image via my activity, so please don't ask me to resize my bitmap. I really don't understand why it just doesn't work as it should.


    EDIT:
    Just to make the problem more understandable. The ImageView height is calculated for each device. It is different for each device. I want the width of my ImageView to be the same as the height as it is. I am using the Two-WayGridView library to show the images if it makes any difference.