Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
149 views
in Technique[技术] by (71.8m points)

android - 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!

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...