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 */ 16package android.support.v7.widget; 17 18import android.content.Context; 19import android.graphics.Canvas; 20import android.graphics.Paint; 21import android.graphics.Rect; 22import android.graphics.RectF; 23import android.view.View; 24 25class CardViewEclairMr1 implements CardViewImpl { 26 27 final RectF sCornerRect = new RectF(); 28 29 @Override 30 public void initStatic() { 31 // Draws a round rect using 7 draw operations. This is faster than using 32 // canvas.drawRoundRect before JBMR1 because API 11-16 used alpha mask textures to draw 33 // shapes. 34 RoundRectDrawableWithShadow.sRoundRectHelper 35 = new RoundRectDrawableWithShadow.RoundRectHelper() { 36 @Override 37 public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, 38 Paint paint) { 39 final float twoRadius = cornerRadius * 2; 40 final float innerWidth = bounds.width() - twoRadius - 1; 41 final float innerHeight = bounds.height() - twoRadius - 1; 42 // increment it to account for half pixels. 43 if (cornerRadius >= 1f) { 44 cornerRadius += .5f; 45 sCornerRect.set(-cornerRadius, -cornerRadius, cornerRadius, cornerRadius); 46 int saved = canvas.save(); 47 canvas.translate(bounds.left + cornerRadius, bounds.top + cornerRadius); 48 canvas.drawArc(sCornerRect, 180, 90, true, paint); 49 canvas.translate(innerWidth, 0); 50 canvas.rotate(90); 51 canvas.drawArc(sCornerRect, 180, 90, true, paint); 52 canvas.translate(innerHeight, 0); 53 canvas.rotate(90); 54 canvas.drawArc(sCornerRect, 180, 90, true, paint); 55 canvas.translate(innerWidth, 0); 56 canvas.rotate(90); 57 canvas.drawArc(sCornerRect, 180, 90, true, paint); 58 canvas.restoreToCount(saved); 59 //draw top and bottom pieces 60 canvas.drawRect(bounds.left + cornerRadius - 1f, bounds.top, 61 bounds.right - cornerRadius + 1f, bounds.top + cornerRadius, 62 paint); 63 canvas.drawRect(bounds.left + cornerRadius - 1f, 64 bounds.bottom - cornerRadius + 1f, bounds.right - cornerRadius + 1f, 65 bounds.bottom, paint); 66 } 67//// center 68 canvas.drawRect(bounds.left, bounds.top + Math.max(0, cornerRadius - 1f), 69 bounds.right, bounds.bottom - cornerRadius + 1f, paint); 70 } 71 }; 72 } 73 74 @Override 75 public void initialize(CardViewDelegate cardView, Context context, int backgroundColor, 76 float radius, float elevation, float maxElevation) { 77 RoundRectDrawableWithShadow background = createBackground(context, backgroundColor, radius, 78 elevation, maxElevation); 79 background.setAddPaddingForCorners(cardView.getPreventCornerOverlap()); 80 cardView.setBackgroundDrawable(background); 81 updatePadding(cardView); 82 } 83 84 RoundRectDrawableWithShadow createBackground(Context context, int backgroundColor, 85 float radius, float elevation, float maxElevation) { 86 return new RoundRectDrawableWithShadow(context.getResources(), backgroundColor, radius, 87 elevation, maxElevation); 88 } 89 90 @Override 91 public void updatePadding(CardViewDelegate cardView) { 92 Rect shadowPadding = new Rect(); 93 getShadowBackground(cardView).getMaxShadowAndCornerPadding(shadowPadding); 94 ((View) cardView).setMinimumHeight((int) Math.ceil(getMinHeight(cardView))); 95 ((View) cardView).setMinimumWidth((int) Math.ceil(getMinWidth(cardView))); 96 cardView.setShadowPadding(shadowPadding.left, shadowPadding.top, 97 shadowPadding.right, shadowPadding.bottom); 98 } 99 100 @Override 101 public void onCompatPaddingChanged(CardViewDelegate cardView) { 102 // NO OP 103 } 104 105 @Override 106 public void onPreventCornerOverlapChanged(CardViewDelegate cardView) { 107 getShadowBackground(cardView).setAddPaddingForCorners(cardView.getPreventCornerOverlap()); 108 updatePadding(cardView); 109 } 110 111 @Override 112 public void setBackgroundColor(CardViewDelegate cardView, int color) { 113 getShadowBackground(cardView).setColor(color); 114 } 115 116 @Override 117 public void setRadius(CardViewDelegate cardView, float radius) { 118 getShadowBackground(cardView).setCornerRadius(radius); 119 updatePadding(cardView); 120 } 121 122 @Override 123 public float getRadius(CardViewDelegate cardView) { 124 return getShadowBackground(cardView).getCornerRadius(); 125 } 126 127 @Override 128 public void setElevation(CardViewDelegate cardView, float elevation) { 129 getShadowBackground(cardView).setShadowSize(elevation); 130 } 131 132 @Override 133 public float getElevation(CardViewDelegate cardView) { 134 return getShadowBackground(cardView).getShadowSize(); 135 } 136 137 @Override 138 public void setMaxElevation(CardViewDelegate cardView, float maxElevation) { 139 getShadowBackground(cardView).setMaxShadowSize(maxElevation); 140 updatePadding(cardView); 141 } 142 143 @Override 144 public float getMaxElevation(CardViewDelegate cardView) { 145 return getShadowBackground(cardView).getMaxShadowSize(); 146 } 147 148 @Override 149 public float getMinWidth(CardViewDelegate cardView) { 150 return getShadowBackground(cardView).getMinWidth(); 151 } 152 153 @Override 154 public float getMinHeight(CardViewDelegate cardView) { 155 return getShadowBackground(cardView).getMinHeight(); 156 } 157 158 private RoundRectDrawableWithShadow getShadowBackground(CardViewDelegate cardView) { 159 return ((RoundRectDrawableWithShadow) cardView.getBackground()); 160 } 161} 162