Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android image view top crop

I'm developing an android application and i need a header to use at the top of the screen similar to an action bar ..... i want it to be transparent but when you start to scroll the view all the content of the view goes behind it so i decided to use an image view (it has to be different in any fragment that's why i didn't use action bar) so i used a frame layout and fixed the image view at the top with the height of 50 and i used the same background of the main view as the source of the image view .... my problem is the scale type i used Center Crop in the main view and it's perfect but it's useless in the header so i'm looking for some thing like this : enter image description here

which is exactly like center crop but crops from the top of the image . i used this link but it wasn't what i'm looking for .....

like image 887
user1631100 Avatar asked Mar 21 '23 07:03

user1631100


2 Answers

Top Crop ImageView:

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.widget.ImageView;


public class TopCropImageView extends ImageView {
    private Matrix mMatrix;
    private boolean mHasFrame;

    @SuppressWarnings("UnusedDeclaration")
    public TopCropImageView(Context context) {
        this(context, null, 0);
    }

    @SuppressWarnings("UnusedDeclaration")
    public TopCropImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @SuppressWarnings("UnusedDeclaration")
    public TopCropImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mHasFrame = false;
        mMatrix = new Matrix();
        // we have to use own matrix because:
        // ImageView.setImageMatrix(Matrix matrix) will not call
        // configureBounds(); invalidate(); because we will operate on ImageView object
    }

    @Override
    protected boolean setFrame(int l, int t, int r, int b)
    {
        boolean changed = super.setFrame(l, t, r, b);
        if (changed) {
            mHasFrame = true;
            // we do not want to call this method if nothing changed
            setupScaleMatrix(r-l, b-t);
        }
        return changed;
    }

    private void setupScaleMatrix(int width, int height) {
        if (!mHasFrame) {
            // we have to ensure that we already have frame
            // called and have width and height
            return;
        }
        final Drawable drawable = getDrawable();
        if (drawable == null) {
            // we have to check if drawable is null because
            // when not initialized at startup drawable we can
            // rise NullPointerException
            return;
        }
        Matrix matrix = mMatrix;
        final int intrinsicWidth = drawable.getIntrinsicWidth();
        final int intrinsicHeight = drawable.getIntrinsicHeight();

        float factorWidth = width/(float) intrinsicWidth;
        float factorHeight = height/(float) intrinsicHeight;
        float factor = Math.max(factorHeight, factorWidth);

        // there magic happen and can be adjusted to current
        // needs
        matrix.setTranslate(-intrinsicWidth/2.0f, 0);
        matrix.postScale(factor, factor, 0, 0);
        matrix.postTranslate(width/2.0f, 0);
        setImageMatrix(matrix);
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        super.setImageDrawable(drawable);
        // We have to recalculate image after chaning image
        setupScaleMatrix(getWidth(), getHeight());
    }

    @Override
    public void setImageResource(int resId) {
        super.setImageResource(resId);
        // We have to recalculate image after chaning image
        setupScaleMatrix(getWidth(), getHeight());
    }

    @Override
    public void setImageURI(Uri uri) {
        super.setImageURI(uri);
        // We have to recalculate image after chaning image
        setupScaleMatrix(getWidth(), getHeight());
    }

    // We do not have to overide setImageBitmap because it calls 
    // setImageDrawable method

}
like image 91
Harshal Bhatt Avatar answered Mar 28 '23 20:03

Harshal Bhatt


I managed to get this working with the PhotoView library that can be found here: https://github.com/chrisbanes/PhotoView

All you need to do is set the library up and on the image view you are using set the scale type to CENTER_CROP. Then in the library go to the PhotoViewAttacher.java file and under the method updateBaseMatrix() where the code for CENTER_CROP is, change it to the following:

    else if (mScaleType == ScaleType.CENTER_CROP) {
     float scale = Math.max(widthScale, heightScale);
     mBaseMatrix.postScale(scale, scale);
     //Changed dy = 0 for top crop
     mBaseMatrix.postTranslate((viewWidth - drawableWidth * scale) / 2F,
         0);

Basically, you set dy=0 so that the matrix stays at the top of the image on the y axis and doesn't center it. And the CENTER_CROP scale type will behave like a TOP_CROP

like image 26
Uwais Iqbal Avatar answered Mar 28 '23 19:03

Uwais Iqbal