CircleImageView.java revision dd27d55a5152f86c07758067e587bdd5b719abaf
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 34 * platforms. 35 * 36 * @hide 37 */ 38class CircleImageView extends ImageView { 39 40 private static final int KEY_SHADOW_COLOR = 0x1E000000; 41 private static final int FILL_SHADOW_COLOR = 0x3D000000; 42 // PX 43 private static final float X_OFFSET = 0f; 44 private static final float Y_OFFSET = 1.75f; 45 private static final float SHADOW_RADIUS = 3.5f; 46 private static final int SHADOW_ELEVATION = 4; 47 48 private Animation.AnimationListener mListener; 49 50 public CircleImageView(Context context, int color, final float radius) { 51 super(context); 52 final float density = getContext().getResources().getDisplayMetrics().density; 53 final int diameter = (int) (radius * density * 2); 54 final int shadowRadius = (int) (density * SHADOW_RADIUS); 55 final int shadowYOffset = (int) (density * Y_OFFSET); 56 final int shadowXOffset = (int) (density * X_OFFSET); 57 ShapeDrawable circle; 58 if (android.os.Build.VERSION.CODENAME.equals("L") 59 || android.os.Build.VERSION.SDK_INT > 21) { 60 circle = new ShapeDrawable(new OvalShape()); 61 ViewCompat.setElevation(this, SHADOW_ELEVATION * density); 62 } else { 63 OvalShape oval = new OvalShape() { 64 Paint shadowPaint = new Paint(); 65 RadialGradient gradient; 66 67 @Override 68 public void draw(Canvas canvas, Paint paint) { 69 if (gradient == null) { 70 gradient = new RadialGradient(diameter/2, diameter/2, shadowRadius, 71 new int[]{FILL_SHADOW_COLOR, 0x00000000}, 72 null, Shader.TileMode.CLAMP); 73 shadowPaint.setShader(gradient); 74 } 75 canvas.drawCircle(diameter / 2, diameter / 2, (diameter / 2), shadowPaint); 76 canvas.drawCircle(diameter / 2, diameter / 2, (diameter / 2 - shadowRadius), 77 paint); 78 } 79 }; 80 circle = new ShapeDrawable(oval); 81 ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, circle.getPaint()); 82 circle.getPaint().setShadowLayer(shadowRadius, shadowXOffset, shadowYOffset, KEY_SHADOW_COLOR); 83 final int padding = (int) (shadowRadius / 2); 84 // set padding so the inner image sits correctly within the shadow. 85 setPadding(padding, padding, padding, padding); 86 } 87 circle.getPaint().setColor(color); 88 setBackgroundDrawable(circle); 89 } 90 91 public void setAnimationListener(Animation.AnimationListener listener) { 92 mListener = listener; 93 } 94 95 @Override 96 public void onAnimationStart() { 97 super.onAnimationStart(); 98 if (mListener != null) { 99 mListener.onAnimationStart(getAnimation()); 100 } 101 } 102 103 @Override 104 public void onAnimationEnd() { 105 super.onAnimationEnd(); 106 if (mListener != null) { 107 mListener.onAnimationEnd(getAnimation()); 108 } 109 } 110 111 /** 112 * Update the background color of the circle image view. 113 */ 114 public void setBackgroundColor(int colorRes) { 115 if (getBackground() instanceof ShapeDrawable) { 116 final Resources res = getResources(); 117 ((ShapeDrawable) getBackground()).getPaint().setColor(res.getColor(colorRes)); 118 } 119 } 120} 121