1 /* 2 * Copyright (C) 2021 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 17 package com.google.android.setupdesign.widget; 18 19 import android.graphics.Canvas; 20 import android.graphics.ColorFilter; 21 import android.graphics.Paint; 22 import android.graphics.Path; 23 import android.graphics.Path.Direction; 24 import android.graphics.Path.FillType; 25 import android.graphics.PixelFormat; 26 import android.graphics.Rect; 27 import android.graphics.RectF; 28 import android.graphics.drawable.Drawable; 29 import androidx.annotation.ColorInt; 30 import androidx.annotation.Nullable; 31 32 /** A rounded rectangle drawable. */ 33 public class CardBackgroundDrawable extends Drawable { 34 private final float inset; 35 36 private final Paint paint; 37 private final RectF cardBounds = new RectF(); 38 private final Path clipPath = new Path(); 39 40 private float cornerRadius; 41 private boolean dirty = false; 42 43 /** 44 * @param color Background color of the card to be rendered 45 * @param radius Corner rounding radius 46 * @param inset Inset from the edge of the canvas to the card 47 */ CardBackgroundDrawable(@olorInt int color, float radius, float inset)48 public CardBackgroundDrawable(@ColorInt int color, float radius, float inset) { 49 cornerRadius = radius; 50 paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 51 paint.setColor(color); 52 this.inset = inset; 53 } 54 55 @Override onBoundsChange(Rect bounds)56 public void onBoundsChange(Rect bounds) { 57 super.onBoundsChange(bounds); 58 dirty = true; 59 } 60 61 @Override setColorFilter(@ullable ColorFilter cf)62 public void setColorFilter(@Nullable ColorFilter cf) { 63 paint.setColorFilter(cf); 64 } 65 66 @Override getOpacity()67 public int getOpacity() { 68 return PixelFormat.OPAQUE; 69 } 70 setCornerRadius(float radius)71 public void setCornerRadius(float radius) { 72 if (cornerRadius == radius) { 73 return; 74 } 75 76 cornerRadius = radius; 77 dirty = true; 78 invalidateSelf(); 79 } 80 81 @Override draw(Canvas canvas)82 public void draw(Canvas canvas) { 83 if (dirty) { 84 buildComponents(getBounds()); 85 dirty = false; 86 } 87 88 if (cornerRadius > 0) { 89 canvas.clipPath(clipPath); 90 } 91 } 92 93 @Override setAlpha(int alpha)94 public void setAlpha(int alpha) {} 95 buildComponents(Rect bounds)96 private void buildComponents(Rect bounds) { 97 cardBounds.set(bounds); 98 cardBounds.inset(inset, inset); 99 100 clipPath.reset(); 101 clipPath.setFillType(FillType.EVEN_ODD); 102 clipPath.addRoundRect(cardBounds, cornerRadius, cornerRadius, Direction.CW); 103 } 104 } 105