Home | History | Annotate | Download | only in chips
      1 package com.android.ex.chips;
      2 
      3 import android.content.Context;
      4 import android.graphics.Bitmap;
      5 import android.graphics.BitmapShader;
      6 import android.graphics.Canvas;
      7 import android.graphics.Color;
      8 import android.graphics.Matrix;
      9 import android.graphics.Paint;
     10 import android.graphics.RectF;
     11 import android.graphics.Shader;
     12 import android.graphics.drawable.BitmapDrawable;
     13 import android.graphics.drawable.Drawable;
     14 import android.graphics.drawable.StateListDrawable;
     15 import android.util.AttributeSet;
     16 import android.widget.ImageView;
     17 
     18 /**
     19  * An ImageView class with a circle mask so that all images are drawn in a
     20  * circle instead of a square.
     21  */
     22 public class CircularImageView extends ImageView {
     23     private static float circularImageBorder = 1f;
     24 
     25     private final Matrix matrix;
     26     private final RectF source;
     27     private final RectF destination;
     28     private final Paint bitmapPaint;
     29     private final Paint borderPaint;
     30 
     31     public CircularImageView(Context context) {
     32         this(context, null, 0);
     33     }
     34 
     35     public CircularImageView(Context context, AttributeSet attrs) {
     36         this(context, attrs, 0);
     37     }
     38 
     39     public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
     40         super(context, attrs, defStyle);
     41 
     42         matrix = new Matrix();
     43         source = new RectF();
     44         destination = new RectF();
     45 
     46         bitmapPaint = new Paint();
     47         bitmapPaint.setAntiAlias(true);
     48         bitmapPaint.setFilterBitmap(true);
     49         bitmapPaint.setDither(true);
     50 
     51         borderPaint = new Paint();
     52         borderPaint.setColor(Color.TRANSPARENT);
     53         borderPaint.setStyle(Paint.Style.STROKE);
     54         borderPaint.setStrokeWidth(circularImageBorder);
     55         borderPaint.setAntiAlias(true);
     56     }
     57 
     58     @Override
     59     protected void onDraw(Canvas canvas) {
     60         Drawable drawable = getDrawable();
     61         BitmapDrawable bitmapDrawable = null;
     62         // support state list drawable by getting the current state
     63         if (drawable instanceof StateListDrawable) {
     64             if (((StateListDrawable) drawable).getCurrent() != null) {
     65                 bitmapDrawable = (BitmapDrawable) drawable.getCurrent();
     66             }
     67         } else {
     68             bitmapDrawable = (BitmapDrawable) drawable;
     69         }
     70 
     71         if (bitmapDrawable == null) {
     72             return;
     73         }
     74         Bitmap bitmap = bitmapDrawable.getBitmap();
     75         if (bitmap == null) {
     76             return;
     77         }
     78 
     79         source.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
     80         destination.set(getPaddingLeft(), getPaddingTop(), getWidth() - getPaddingRight(),
     81                 getHeight() - getPaddingBottom());
     82 
     83         drawBitmapWithCircleOnCanvas(bitmap, canvas, source, destination);
     84     }
     85 
     86     /**
     87      * Given the source bitmap and a canvas, draws the bitmap through a circular
     88      * mask. Only draws a circle with diameter equal to the destination width.
     89      *
     90      * @param bitmap The source bitmap to draw.
     91      * @param canvas The canvas to draw it on.
     92      * @param source The source bound of the bitmap.
     93      * @param dest The destination bound on the canvas.
     94      */
     95     public void drawBitmapWithCircleOnCanvas(Bitmap bitmap, Canvas canvas,
     96                                              RectF source, RectF dest) {
     97         // Draw bitmap through shader first.
     98         BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,
     99                 Shader.TileMode.CLAMP);
    100         matrix.reset();
    101 
    102         // Fit bitmap to bounds.
    103         matrix.setRectToRect(source, dest, Matrix.ScaleToFit.FILL);
    104 
    105         shader.setLocalMatrix(matrix);
    106         bitmapPaint.setShader(shader);
    107         canvas.drawCircle(dest.centerX(), dest.centerY(), dest.width() / 2f,
    108                 bitmapPaint);
    109 
    110         // Then draw the border.
    111         canvas.drawCircle(dest.centerX(), dest.centerY(),
    112                 dest.width() / 2f - circularImageBorder / 2, borderPaint);
    113     }
    114 }