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