CircleImageView.java revision 96dfc170940d2f7218317242115eda1273863966
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v4.widget; 18 19import android.content.Context; 20import android.content.res.Resources; 21import android.graphics.Canvas; 22import android.graphics.Paint; 23import android.graphics.RadialGradient; 24import android.graphics.Shader; 25import android.graphics.drawable.ShapeDrawable; 26import android.graphics.drawable.shapes.OvalShape; 27import android.support.v4.view.ViewCompat; 28import android.view.animation.Animation; 29import android.widget.ImageView; 30 31/** 32 * Private class created to work around issues with AnimationListeners being 33 * called before the animation is actually complete and support shadows on older platforms. 34 */ 35class CircleImageView extends ImageView { 36 37 private static final int KEY_SHADOW_COLOR = 0x1E000000; 38 private static final int FILL_SHADOW_COLOR = 0x3D000000; 39 // PX 40 private static final float X_OFFSET = 0f; 41 private static final float Y_OFFSET = 1.75f; 42 private static final float SHADOW_RADIUS = 3.5f; 43 private static final int SHADOW_ELEVATION = 4; 44 45 private Animation.AnimationListener mListener; 46 47 public CircleImageView(Context context, int color, final float radius) { 48 super(context); 49 final float density = getContext().getResources().getDisplayMetrics().density; 50 final int diameter = (int) (radius * density * 2); 51 final int shadowRadius = (int) (density * SHADOW_RADIUS); 52 final int shadowYOffset = (int) (density * Y_OFFSET); 53 final int shadowXOffset = (int) (density * X_OFFSET); 54 ShapeDrawable circle; 55 if (android.os.Build.VERSION.CODENAME.equals("L") 56 || android.os.Build.VERSION.SDK_INT > 21) { 57 circle = new ShapeDrawable(new OvalShape()); 58 ViewCompat.setElevation(this, SHADOW_ELEVATION * density); 59 } else { 60 OvalShape oval = new OvalShape() { 61 Paint shadowPaint = new Paint(); 62 RadialGradient gradient; 63 64 @Override 65 public void draw(Canvas canvas, Paint paint) { 66 if (gradient == null) { 67 gradient = new RadialGradient(diameter/2, diameter/2, shadowRadius, 68 new int[]{FILL_SHADOW_COLOR, 0x00000000}, 69 null, Shader.TileMode.CLAMP); 70 shadowPaint.setShader(gradient); 71 } 72 canvas.drawCircle(diameter / 2, diameter / 2, (diameter / 2), shadowPaint); 73 canvas.drawCircle(diameter / 2, diameter / 2, (diameter / 2 - shadowRadius), 74 paint); 75 } 76 }; 77 circle = new ShapeDrawable(oval); 78 ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, circle.getPaint()); 79 circle.getPaint().setShadowLayer(shadowRadius, shadowXOffset, shadowYOffset, KEY_SHADOW_COLOR); 80 final int padding = (int) (shadowRadius / 2); 81 // set padding so the inner image sits correctly within the shadow. 82 setPadding(padding, padding, padding, padding); 83 } 84 circle.getPaint().setColor(color); 85 setBackgroundDrawable(circle); 86 } 87 88 public void setAnimationListener(Animation.AnimationListener listener) { 89 mListener = listener; 90 } 91 92 @Override 93 public void onAnimationStart() { 94 super.onAnimationStart(); 95 if (mListener != null) { 96 mListener.onAnimationStart(getAnimation()); 97 } 98 } 99 100 @Override 101 public void onAnimationEnd() { 102 super.onAnimationEnd(); 103 if (mListener != null) { 104 mListener.onAnimationEnd(getAnimation()); 105 } 106 } 107 108 /** 109 * Update the background color of the circle image view. 110 */ 111 public void setBackgroundColor(int colorRes) { 112 if (getBackground() instanceof ShapeDrawable) { 113 final Resources res = getResources(); 114 ((ShapeDrawable) getBackground()).getPaint().setColor(res.getColor(colorRes)); 115 } 116 } 117} 118