package com.github.ivbaranov.mli; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import com.example.ivbaranov.ma.R; public class MaterialLetterIcon extends View { public final static int SHAPE_CIRCLE = 0; public final static int SHAPE_RECT = 1; private final static Rect textBounds = new Rect(); private final static int DEFAULT_SHAPE_COLOR = Color.BLACK; private final static int DEFAULT_SHAPE = SHAPE_CIRCLE; private final static int DEFAULT_LETTER_COLOR = Color.WHITE; private final static int DEFAULT_LETTER_SIZE = 26; private final static String DEFAULT_FONT_PATH = "fonts/Roboto-Light.ttf"; private final static int DEFAULT_LETTERS_NUMBER = 1; private final static boolean DEFAULT_INITIALS_STATE = false; private final static int DEFAULT_INITIALS_NUMBER = 2; private Context context; private Paint mShapePaint; private Paint mLetterPaint; private int mShapeColor; private int mShapeType; private String mLetter; private int mLetterColor; private int mLetterSize; private int mLettersNumber; private boolean mInitials; private int mInitialsNumber; private String mOriginalLetter; public MaterialLetterIcon(Context context) { super(context); init(context, null, 0, 0); } public MaterialLetterIcon(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs, 0, 0); } public MaterialLetterIcon(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr, 0); } public MaterialLetterIcon(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr, defStyleRes); } /** * Initialize the default values * <ul> * <li>shape color = black</li> * <li>shape type = circle</li> * <li>letter color = white</li> * <li>letter size = 26 sp</li> * <li>number of letters = 1</li> * <li>typeface = Roboto Light</li> * <li>initials = false</li> * <li>initials number = 2</li> * </ul> */ private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { this.context = context; mShapeColor = DEFAULT_SHAPE_COLOR; mShapeType = DEFAULT_SHAPE; mLetterColor = DEFAULT_LETTER_COLOR; mLetterSize = DEFAULT_LETTER_SIZE; mLettersNumber = DEFAULT_LETTERS_NUMBER; mInitials = DEFAULT_INITIALS_STATE; mInitialsNumber = DEFAULT_INITIALS_NUMBER; mShapePaint = new Paint(); mShapePaint.setStyle(Paint.Style.FILL); mShapePaint.setAntiAlias(true); mLetterPaint = new Paint(); mLetterPaint.setAntiAlias(true); mLetterPaint.setTypeface(Typeface.createFromAsset(context.getAssets(), DEFAULT_FONT_PATH)); if (!isInEditMode() && attrs != null) { initAttributes(context, attrs); } } private void initAttributes(Context context, AttributeSet attributeSet) { TypedArray attr = getTypedArray(context, attributeSet, R.styleable.MaterialLetterIcon); if (attr != null) { try { mShapeColor = attr.getColor(R.styleable.MaterialLetterIcon_mli_shape_color, DEFAULT_SHAPE_COLOR); mInitials = attr.getBoolean(R.styleable.MaterialLetterIcon_mli_initials, DEFAULT_INITIALS_STATE); mInitialsNumber = attr.getInt(R.styleable.MaterialLetterIcon_mli_initials_number, DEFAULT_INITIALS_NUMBER); mOriginalLetter = attr.getString(R.styleable.MaterialLetterIcon_mli_letter); if (mOriginalLetter != null) { setLetter(mOriginalLetter); } mShapeType = attr.getInt(R.styleable.MaterialLetterIcon_mli_shape_type, DEFAULT_SHAPE); mLetterColor = attr.getColor(R.styleable.MaterialLetterIcon_mli_letter_color, DEFAULT_LETTER_COLOR); mLetterSize = attr.getInt(R.styleable.MaterialLetterIcon_mli_letter_size, DEFAULT_LETTER_SIZE); mLettersNumber = attr.getInt(R.styleable.MaterialLetterIcon_mli_letters_number, DEFAULT_LETTERS_NUMBER); } finally { attr.recycle(); } } } private TypedArray getTypedArray(Context context, AttributeSet attributeSet, int[] attr) { return context.obtainStyledAttributes(attributeSet, attr, 0, 0); } @Override protected void onDraw(Canvas canvas) { int viewWidthHalf = this.getMeasuredWidth() / 2; int viewHeightHalf = this.getMeasuredHeight() / 2; int radius; if (viewWidthHalf > viewHeightHalf) { radius = viewHeightHalf; } else { radius = viewWidthHalf; } switch (mShapeType) { case SHAPE_CIRCLE: drawCircle(canvas, radius, viewWidthHalf, viewHeightHalf); break; case SHAPE_RECT: drawRect(canvas, this.getMeasuredWidth(), this.getMeasuredWidth()); break; } if (mLetter != null) { drawLetter(canvas, viewWidthHalf, viewHeightHalf); } } private void drawCircle(Canvas canvas, int radius, int width, int height) { mShapePaint.setColor(mShapeColor); canvas.drawCircle(width, height, radius, mShapePaint); } private void drawRect(Canvas canvas, int width, int height) { mShapePaint.setColor(mShapeColor); canvas.drawRect(0, 0, width, height, mShapePaint); } private void drawLetter(Canvas canvas, float cx, float cy) { mLetterPaint.setColor(mLetterColor); mLetterPaint.setTextSize(spToPx(mLetterSize, context.getResources())); if (mInitials) { mLetterPaint.getTextBounds(mLetter, 0, mInitialsNumber > mLetter.length() ? mLetter.length() : mInitialsNumber, textBounds); } else { mLetterPaint.getTextBounds(mLetter, 0, mLettersNumber > mLetter.length() ? mLetter.length() : mLettersNumber, textBounds); } canvas.drawText(mLetter, cx - textBounds.exactCenterX(), cy - textBounds.exactCenterY(), mLetterPaint); } /** * Sets color to shape. * * @param color a color integer associated with a particular resource id */ public void setShapeColor(int color) { this.mShapeColor = color; invalidate(); } /** * Sets shape type. * * @param type one of shapes to draw: {@code MaterialLetterIcon.SHAPE_CIRCLE} or {@code * MaterialLetterIcon.SHAPE_RECT} */ public void setShapeType(int type) { this.mShapeType = type; invalidate(); } /** * Set letters. * * @param string a string to take letters from */ public void setLetter(String string) { if (string == null || string.isEmpty()) { return; } this.mOriginalLetter = string; int desireLength; if (mInitials) { String initials[] = string.split("\\s+"); StringBuilder initialsPlain = new StringBuilder(mLettersNumber); for (String initial : initials) { initialsPlain.append(initial.substring(0, 1)); } this.mLetter = initialsPlain.toString(); desireLength = mInitialsNumber; } else { this.mLetter = String.valueOf(string.replaceAll("\\s+", "")); desireLength = mLettersNumber; } this.mLetter = mLetter.substring(0, desireLength > mLetter.length() ? mLetter.length() : desireLength) .toUpperCase(); invalidate(); } /** * Set letters color. * * @param color a color integer associated with a particular resource id */ public void setLetterColor(int color) { this.mLetterColor = color; invalidate(); } /** * Set letters size. * * @param size size of letter in SP */ public void setLetterSize(int size) { this.mLetterSize = size; invalidate(); } /** * Set number of letters to be displayed. * * @param num number of letters */ public void setLettersNumber(int num) { this.mLettersNumber = num; invalidate(); } /** * Set letters typeface. * * @param typeface a typeface to apply to letter */ public void setLetterTypeface(Typeface typeface) { this.mLetterPaint.setTypeface(typeface); invalidate(); } /** * Set initials state. * * @param state if true, gets first letter of {@code initialsNumber} words in provided string */ public void setInitials(boolean state) { this.mInitials = state; setLetter(mOriginalLetter); } /** * Set number of initials to show. * * @param initialsNumber number of initials to show */ public void setInitialsNumber(int initialsNumber) { this.mInitialsNumber = initialsNumber; setLetter(mOriginalLetter); } public Paint getShapePaint() { return mShapePaint; } public Paint getLetterPaint() { return mLetterPaint; } public int getShapeColor() { return mShapeColor; } public int getShapeType() { return mShapeType; } public String getLetter() { return mLetter; } public int getLetterColor() { return mLetterColor; } public int getLetterSize() { return mLetterSize; } public int getLettersNumber() { return mLettersNumber; } public boolean isInitials() { return mInitials; } public int getInitialsNumber() { return mInitialsNumber; } /** * Convert sp to pixel. */ private static int spToPx(float sp, Resources resources) { float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, resources.getDisplayMetrics()); return (int) px; } /** * Builder. */ public static final class Builder { private final Context context; private int mShapeColor = DEFAULT_SHAPE_COLOR; private int mShapeType = DEFAULT_SHAPE; private String mLetter; private int mLetterColor = DEFAULT_LETTER_COLOR; private int mLetterSize = DEFAULT_LETTER_SIZE; private int mLettersNumber = DEFAULT_LETTERS_NUMBER; private Typeface mLetterTypeface; private boolean mInitials = DEFAULT_INITIALS_STATE; private int mInitialsNumber = DEFAULT_INITIALS_NUMBER; public Builder(Context context) { this.context = context; this.mLetterTypeface = Typeface.createFromAsset(context.getAssets(), DEFAULT_FONT_PATH); } public Builder shapeColor(int color) { this.mShapeColor = color; return this; } public Builder shapeType(int type) { this.mShapeType = type; return this; } public Builder letter(String letter) { this.mLetter = letter; return this; } public Builder letterColor(int color) { this.mLetterColor = color; return this; } public Builder letterSize(int size) { this.mLetterSize = size; return this; } public Builder lettersNumber(int num) { this.mLettersNumber = num; return this; } public Builder letterTypeface(Typeface typeface) { this.mLetterTypeface = typeface; return this; } public Builder initials(boolean state) { this.mInitials = state; return this; } public Builder initialsNumber(int num) { this.mInitialsNumber = num; return this; } public MaterialLetterIcon create() { MaterialLetterIcon icon = new MaterialLetterIcon(context); icon.setShapeColor(mShapeColor); icon.setShapeType(mShapeType); icon.setLetter(mLetter); icon.setLetterColor(mLetterColor); icon.setLetterSize(mLetterSize); icon.setLettersNumber(mLettersNumber); icon.setLetterTypeface(mLetterTypeface); icon.setInitials(mInitials); icon.setInitialsNumber(mInitialsNumber); return icon; } } }