6

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.

LaurentY
  • 7,495
  • 3
  • 37
  • 55
idish
  • 3,190
  • 12
  • 53
  • 85
  • I don't understand what the problem is. What do you mean "I want the Width of it to be the same"? The same as what? are you expecting a square image? Is you image view of square shape? I don't understand. – HalR Jul 27 '13 at 19:23
  • If your ImageView were 100x100, then using fitXY would create a 100x100 image on the screen. As it is, it looks like you have a 100x200 size ImageView, or some similar thing. – HalR Jul 27 '13 at 19:24
  • @HalR I'm expecting a square image, yes. I want the size of the width to be the same as the height.(Bigger). The height of my imageview is scaled automatically - it's totally fine. but the Width, is too low. I want it to be the same as my height. How can I do it? even programatically. – idish Jul 27 '13 at 20:42
  • Your layout is setting the imageview width and height to be the width and height of its parent. Then fitxy is fitting the image within this box. If you want the imageView to be 100 by 100, why don't you just set it the xml height and widht parameters to 100dp instead of matchparent? – HalR Jul 27 '13 at 20:52
  • @HalR I never said I want my imageview to be 100 by 100. I said I'm saving the bitmap on 100 by 100. The imageview height is calculated for each device. It different for each device. I want the width of my imageview, to be the same as the height as it is. – idish Jul 27 '13 at 21:02
  • Have you tried a grid layout like this: http://www.androidhive.info/2012/02/android-gridview-layout-tutorial/ ? – HalR Jul 27 '13 at 21:05
  • @HalR I have been going through this, I'm using the TwoWay Grid View. – idish Jul 27 '13 at 21:19
  • @HalR Ah.. do you have any idea in your mind..? using FITXY should create a Square Imageview and it just doesn't happen. – idish Jul 27 '13 at 21:28

4 Answers4

10

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.

Community
  • 1
  • 1
Geobits
  • 22,218
  • 6
  • 59
  • 103
  • My target is to make the same gallery as the original gallery app. As I understood from their architecture, when the device is in portrait mode, there are 2 rows. and all the displayed images are square. Please, if you can, look at the Gallery to better understand what I'm looking for. Thanks :) – idish Jul 29 '13 at 17:47
  • BTW, I know that a normal GridView will work, But I'm looking for a horizontal one :) – idish Jul 29 '13 at 17:48
  • Ah, horizontal. Makes sense for a gallery. Well, the best way to go about it is overriding the `onMeasure` of each item, like I said above. It's simple, only a few lines of code, and has worked for me in the past. – Geobits Jul 29 '13 at 17:50
  • Actually, I've already tried it, but I'll give it another shot now :) – idish Jul 29 '13 at 17:56
  • WOW, that's just works. I can't believe that!!! So great. I just had to edit the code so that the height will be the same and not the width. :) You're great seriously. I'm so happy right now. I was looking for this kind of solution for a real long time. – idish Jul 29 '13 at 18:47
3

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>
Hogun
  • 602
  • 6
  • 9
1

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"
/>
Ahmad Raza
  • 2,850
  • 1
  • 21
  • 37
  • You should use android:layout_width="100dp" and android:layout_height="100dp" for exact 100x100 imageview. Thanks! – Ahmad Raza Jul 29 '13 at 17:35
  • From OP's comments: *"I never said I want my imageview to be 100 by 100. I said I'm saving the bitmap on 100 by 100. The imageview height is calculated for each device. It different for each device."* – Geobits Jul 29 '13 at 17:41
  • instead of using "match_parent", you should use "wrap_content". Then imageView size will be according to your bitmap, And also must use background property instead of src. – Ahmad Raza Jul 29 '13 at 17:45
-2

Use background with fitxy instead of using src. It will stretch your image:

android:background="@drawable/locked_image"
android:scaleType="fitXY"
Nikolay Mihaylov
  • 3,868
  • 8
  • 27
  • 32