package com.rey.material.drawable; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.text.BoringLayout; import android.text.Layout; import android.text.TextPaint; import android.text.TextUtils; import android.util.FloatMath; /** * Created by Rey on 1/21/2015. */ public class ContactChipDrawable extends Drawable{ private Paint mPaint; private int mPaddingLeft; private int mPaddingRight; private int mBackgroundColor; private CharSequence mContactName; private BoringLayout mBoringLayout; private BoringLayout.Metrics mMetrics; private TextPaint mTextPaint; private RectF mRect; private BitmapShader mBitmapShader; private Bitmap mBitmap; private Matrix mMatrix; public ContactChipDrawable(int paddingLeft, int paddingRight, Typeface typeface, int textColor, int textSize, int backgroundColor) { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(textColor); mPaint.setTypeface(typeface); mPaint.setTextSize(textSize); mTextPaint = new TextPaint(mPaint); mMetrics = new BoringLayout.Metrics(); Paint.FontMetricsInt temp = mTextPaint.getFontMetricsInt(); mMetrics.ascent = temp.ascent; mMetrics.bottom = temp.bottom; mMetrics.descent = temp.descent; mMetrics.top = temp.top; mMetrics.leading = temp.leading; mRect = new RectF(); mMatrix = new Matrix(); mPaddingLeft = paddingLeft; mPaddingRight = paddingRight; mBackgroundColor = backgroundColor; } public void setContactName(CharSequence name){ mContactName = name; updateLayout(); invalidateSelf(); } public void setImage(Bitmap bm){ if(mBitmap != bm){ mBitmap = bm; if(mBitmap != null) { mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); updateMatrix(); } invalidateSelf(); } } private void updateLayout(){ if(mContactName == null) return; Rect bounds = getBounds(); if(bounds.width() == 0 || bounds.height() == 0) return; int outerWidth = Math.max(0, bounds.width() - bounds.height() - mPaddingLeft - mPaddingRight); mMetrics.width = (int) FloatMath.ceil(mTextPaint.measureText(mContactName, 0, mContactName.length())); if(mBoringLayout == null) mBoringLayout = BoringLayout.make(mContactName, mTextPaint, outerWidth, Layout.Alignment.ALIGN_NORMAL, 1f, 1f, mMetrics, true, TextUtils.TruncateAt.END, outerWidth); else mBoringLayout = mBoringLayout.replaceOrMake(mContactName, mTextPaint, outerWidth, Layout.Alignment.ALIGN_NORMAL, 1f, 1f, mMetrics, true, TextUtils.TruncateAt.END, outerWidth); } private void updateMatrix(){ if(mBitmap == null) return; Rect bounds = getBounds(); if(bounds.width() == 0 || bounds.height() == 0) return; mMatrix.reset(); float scale = bounds.height() / (float)Math.min(mBitmap.getWidth(), mBitmap.getHeight()); mMatrix.setScale(scale, scale, 0, 0); mMatrix.postTranslate((bounds.height() - mBitmap.getWidth() * scale) / 2, (bounds.height() - mBitmap.getHeight() * scale) / 2); mBitmapShader.setLocalMatrix(mMatrix); } @Override protected void onBoundsChange(Rect bounds) { updateLayout(); updateMatrix(); } @Override public void draw(Canvas canvas) { int saveCount = canvas.save(); Rect bounds = getBounds(); float halfHeight = bounds.height() / 2f; mPaint.setShader(null); mPaint.setColor(mBackgroundColor); mRect.set(1, 0, bounds.height() + 1, bounds.height()); canvas.drawArc(mRect, 90, 180, true, mPaint); mRect.set(bounds.width() - bounds.height(), 0, bounds.width(), bounds.height()); canvas.drawArc(mRect, 270, 180, true, mPaint); mRect.set(halfHeight, 0, bounds.width() - halfHeight, bounds.height()); canvas.drawRect(mRect, mPaint); if(mBitmap != null){ mPaint.setShader(mBitmapShader); canvas.drawCircle(halfHeight, halfHeight, halfHeight, mPaint); } if(mContactName != null && mBoringLayout != null) { canvas.translate(bounds.height() + mPaddingLeft, (bounds.height() - mBoringLayout.getHeight()) / 2f); mBoringLayout.draw(canvas); } canvas.restoreToCount(saveCount); } @Override public void setAlpha(int alpha) { mPaint.setAlpha(alpha); } @Override public void setColorFilter(ColorFilter cf) { mPaint.setColorFilter(cf); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } }