1 package com.android.customization.widget; 2 3 import android.graphics.Canvas; 4 import android.graphics.ColorFilter; 5 import android.graphics.Matrix; 6 import android.graphics.Paint; 7 import android.graphics.Path; 8 import android.graphics.PixelFormat; 9 import android.graphics.Rect; 10 import android.graphics.drawable.Drawable; 11 12 import androidx.core.graphics.PathParser; 13 14 /** 15 * Drawable that draws a grid rows x cols of icon shapes adjusting their size to fit within its 16 * bounds. 17 */ 18 public class GridTileDrawable extends Drawable { 19 20 // Path is expected configuration in following dimension: [100 x 100])) 21 private static final float PATH_SIZE = 100f; 22 // We want each "icon" using 80% of the available size, so there's 10% padding on each side 23 private static final float ICON_SCALE = .8f; 24 private final int mCols; 25 private final int mRows; 26 private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 27 private final Path mShapePath; 28 private final Path mTransformedPath; 29 private final Matrix mScaleMatrix; 30 private float mCellSize = -1f; 31 private float mSpaceBetweenIcons; 32 GridTileDrawable(int cols, int rows, String path)33 public GridTileDrawable(int cols, int rows, String path) { 34 mCols = cols; 35 mRows = rows; 36 37 mShapePath = PathParser.createPathFromPathData(path); 38 mTransformedPath = new Path(mShapePath); 39 mScaleMatrix = new Matrix(); 40 } 41 42 @Override onBoundsChange(Rect bounds)43 protected void onBoundsChange(Rect bounds) { 44 super.onBoundsChange(bounds); 45 mCellSize = (float) bounds.height() / mRows; 46 mSpaceBetweenIcons = mCellSize * ((1 - ICON_SCALE) / 2); 47 48 float scaleFactor = (mCellSize * ICON_SCALE) / PATH_SIZE; 49 mScaleMatrix.setScale(scaleFactor, scaleFactor); 50 mShapePath.transform(mScaleMatrix, mTransformedPath); 51 } 52 53 @Override draw(Canvas canvas)54 public void draw(Canvas canvas) { 55 for (int r = 0; r < mRows; r++) { 56 for (int c = 0; c < mCols; c++) { 57 int saveCount = canvas.save(); 58 float x = (c * mCellSize) + mSpaceBetweenIcons; 59 float y = (r * mCellSize) + mSpaceBetweenIcons; 60 canvas.translate(x, y); 61 canvas.drawPath(mTransformedPath, mPaint); 62 canvas.restoreToCount(saveCount); 63 } 64 } 65 } 66 67 @Override setAlpha(int alpha)68 public void setAlpha(int alpha) { 69 mPaint.setAlpha(alpha); 70 } 71 72 @Override setColorFilter(ColorFilter colorFilter)73 public void setColorFilter(ColorFilter colorFilter) { 74 mPaint.setColorFilter(colorFilter); 75 } 76 77 @Override getOpacity()78 public int getOpacity() { 79 return PixelFormat.TRANSLUCENT; 80 } 81 } 82