Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImageView scaling TOP_CROP

I have an ImageView which is displaying a png that has a bigger aspect ratio than that of the device (vertically speaking - meaning its longer). I want to display this while maintaining aspect ratio, matching the width of the parent, and pinning the imageview to the top of the screen.

The problem i have with using CENTER_CROP as the scale type is that it will (understandable) center the scaled image instead of aligning the top edge to the top edge f the image view.

The problem with FIT_START is that the image will fit the screen height and not fill the width.

I have solved this problem by using a custom ImageView and overriding onDraw(Canvas) and handeling this manually using the canvas; the problem with this approach is that 1) I'm worried there may be a simpler solution, 2) I am getting a VM mem exception when calling super(AttributeSet) in the constructor when trying to set a src img of 330kb when the heap has 3 mb free (with a heap size of 6 mb) and cant work out why.

Any ideas / suggestions / solutions are much welcome :)

Thanks

p.s. i thought that a solution may be to use a matrix scale type and do it myself, but that seems to to be the same or more work than my current solution!

like image 935
Dori Avatar asked Jun 13 '11 11:06

Dori


People also ask

What is ImageView?

An ImageView control is used to display images in Android applications. An image can be displayed by assigning it to the ImageView control and including the android:src attribute in the XML definition of the control. Images can also be dynamically assigned to the ImageView control through Java code.


1 Answers

Ok, I have a working solution. The prompt from Darko made me look again at the ImageView class (thanks) and have applied the transformation using a Matrix (as i originally suspected but did not have success on my first attempt!). In my custom imageView class I call setScaleType(ScaleType.MATRIX) after super() in the constructor, and have the following method.

    @Override     protected boolean setFrame(int l, int t, int r, int b)     {         Matrix matrix = getImageMatrix();          float scaleFactor = getWidth()/(float)getDrawable().getIntrinsicWidth();             matrix.setScale(scaleFactor, scaleFactor, 0, 0);         setImageMatrix(matrix);         return super.setFrame(l, t, r, b);     } 

I have placed int in the setFrame() method as in ImageView the call to configureBounds() is within this method, which is where all the scaling and matrix stuff takes place, so seems logical to me (say if you disagree)

Below is the super.setFrame() method from the AOSP (Android Open Source Project)

    @Override     protected boolean setFrame(int l, int t, int r, int b) {         boolean changed = super.setFrame(l, t, r, b);         mHaveFrame = true;         configureBounds();         return changed;     } 

Find the full class src here

like image 72
Dori Avatar answered Sep 26 '22 02:09

Dori