io.nuclei.cyto.ui.view.GlideImageView.java Source code

Java tutorial

Introduction

Here is the source code for io.nuclei.cyto.ui.view.GlideImageView.java

Source

/**
 * Copyright 2016 YouVersion
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.nuclei.cyto.ui.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.util.Log;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapResource;

import io.nuclei.cyto.R;

public class GlideImageView extends AppCompatImageView {

    static final String TAG = GlideImageView.class.getSimpleName();

    boolean mCircle = false;
    float mRadius;
    float mRatio;
    int mPlaceholderId;
    Uri mUri;
    Transformation mTransformation;
    GlideDrawableListener mListener;
    boolean mSet;

    public GlideImageView(Context context) {
        super(context);
        init(context, null, 0, 0);
    }

    public GlideImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0, 0);
    }

    public GlideImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr, 0);
    }

    protected DiskCacheStrategy getStrategy() {
        return DiskCacheStrategy.ALL;
    }

    void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GlideImageView, defStyleAttr,
                defStyleRes);

        mCircle = a.getBoolean(R.styleable.GlideImageView_circle, false);
        mRatio = a.getFloat(R.styleable.GlideImageView_ratio, 0);
        mRadius = a.getDimensionPixelSize(R.styleable.GlideImageView_radius, 0);
        mPlaceholderId = a.getResourceId(R.styleable.GlideImageView_placeholder, 0);

        String uri = a.getString(R.styleable.GlideImageView_url);
        a.recycle();

        if (uri == null) {
            if (mPlaceholderId > 0) {
                if (mCircle || mRadius > 0) {
                    if (mTransformation == null)
                        mTransformation = new CornerTransformation(getContext(), mCircle, mRadius);
                    Glide.with(getContext()).load(mPlaceholderId).asBitmap().diskCacheStrategy(getStrategy())
                            .transform(mTransformation).into(this);
                } else
                    Glide.with(context).load(mPlaceholderId).into(this);
            }
        } else
            setImageURI(uri);
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        if (mCircle && drawable instanceof BitmapDrawable) {
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            RoundedBitmapDrawable d = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
            d.setCornerRadius(d.getIntrinsicWidth() / 2);
            d.setAntiAlias(true);
            drawable = d;
        }
        super.setImageDrawable(drawable);
        if (mListener != null)
            mListener.onDrawable(drawable);
    }

    public void setListener(GlideDrawableListener listener) {
        mListener = listener;
    }

    public void setAspectRatio(float ratio) {
        mRatio = ratio;
        requestLayout();
    }

    public void setUrl(String url) {
        setImageURI(url);
    }

    public void setImageURI(String uri) {
        setImageURI(uri == null ? null : Uri.parse(uri));
    }

    @Override
    public void setImageURI(Uri uri) {
        mSet = true;
        try {
            mUri = uri;
            RequestManager mgr = Glide.with(getContext());
            if (uri == null) {
                if (mPlaceholderId == 0) {
                    Glide.clear(this);
                    setImageDrawable(null);
                } else {
                    if (mCircle || mRadius > 0) {
                        if (mTransformation == null)
                            mTransformation = new CornerTransformation(getContext(), mCircle, mRadius);
                        mgr.load(mPlaceholderId).asBitmap().transform(mTransformation).into(this);
                    } else
                        mgr.load(mPlaceholderId).into(this);
                }
            } else {
                if (mCircle || mRadius > 0) {
                    if (mTransformation == null)
                        mTransformation = new CornerTransformation(getContext(), mCircle, mRadius);
                    if (mPlaceholderId != 0)
                        mgr.load(uri).asBitmap().diskCacheStrategy(getStrategy()).placeholder(mPlaceholderId)
                                .error(mPlaceholderId).fallback(mPlaceholderId).transform(mTransformation)
                                .into(this);
                    else
                        mgr.load(uri).asBitmap().diskCacheStrategy(getStrategy()).transform(mTransformation)
                                .into(this);
                } else {
                    if (mPlaceholderId != 0)
                        mgr.load(uri).asBitmap().diskCacheStrategy(getStrategy()).placeholder(mPlaceholderId)
                                .into(this);
                    else
                        mgr.load(uri).asBitmap().diskCacheStrategy(getStrategy()).into(this);
                }
            }
        } catch (IllegalArgumentException err) {
            Log.e(TAG, "Error setImageURI", err);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mRatio == 0)
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        else {
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = (int) (width / mRatio);
            setMeasuredDimension(width, height);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (!mSet && (mUri != null || mPlaceholderId != 0))
            setImageURI(mUri);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mSet = false;
        try {
            Glide.clear(this);
        } catch (IllegalArgumentException err) {
            Log.e(TAG, "Error onDetachedFromWindow", err);
        }
        setImageDrawable(null);
    }

    static class CornerTransformation implements Transformation<Bitmap> {

        BitmapPool mBitmapPool;
        boolean mCircle;
        float mRadius;
        RectF mRect;

        public CornerTransformation(Context context, boolean circle, float radius) {
            mBitmapPool = Glide.get(context).getBitmapPool();
            mCircle = circle;
            mRadius = radius;
        }

        @Override
        public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) {
            Bitmap bitmap = resource.get();

            if (mCircle)
                bitmap = circle(bitmap);
            else
                bitmap = round(bitmap);

            return BitmapResource.obtain(bitmap, mBitmapPool);
        }

        Bitmap circle(Bitmap original) {
            int size = Math.min(original.getWidth(), original.getHeight());

            Bitmap bitmap = mBitmapPool.get(size, size, original.getConfig());
            if (bitmap == null)
                bitmap = Bitmap.createBitmap(size, size, original.getConfig());

            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
            BitmapShader shader = new BitmapShader(original, BitmapShader.TileMode.CLAMP,
                    BitmapShader.TileMode.CLAMP);

            int width = (original.getWidth() - size) / 2;
            int height = (original.getHeight() - size) / 2;
            if (width != 0 || height != 0) {
                Matrix matrix = new Matrix();
                matrix.setTranslate(-width, -height);
                shader.setLocalMatrix(matrix);
            }

            paint.setShader(shader);
            paint.setAntiAlias(true);

            float r = size / 2f;
            canvas.drawCircle(r, r, r, paint);

            return bitmap;
        }

        Bitmap round(Bitmap original) {
            int width = original.getWidth();
            int height = original.getHeight();

            Bitmap bitmap = mBitmapPool.get(width, height, original.getConfig());
            if (bitmap == null)
                bitmap = Bitmap.createBitmap(width, height, original.getConfig());

            if (mRect == null)
                mRect = new RectF(0, 0, width, height);
            else
                mRect.set(0, 0, width, height);

            Canvas canvas = new Canvas(bitmap);

            BitmapShader shader = new BitmapShader(original, BitmapShader.TileMode.CLAMP,
                    BitmapShader.TileMode.CLAMP);

            Paint paint = new Paint();
            paint.setShader(shader);
            paint.setAntiAlias(true);

            canvas.drawRoundRect(mRect, mRadius, mRadius, paint);

            return bitmap;
        }

        @Override
        public String getId() {
            return "CornerTransformation(" + mCircle + ", " + mRadius + ")";
        }
    }

    public interface GlideDrawableListener {

        void onDrawable(Drawable drawable);

    }

}