ReplacementDrawableSpan.java revision 6c2a016fb00482339dc66b93822042f9f9e2424f
1package com.android.ex.chips.recipientchip;
2
3import android.graphics.Canvas;
4import android.graphics.Paint;
5import android.graphics.Rect;
6import android.graphics.drawable.Drawable;
7import android.text.style.ReplacementSpan;
8
9/**
10 * ReplacementSpan that properly draws the drawable that is centered around the text
11 * without changing the default text size or layout.
12 */
13public class ReplacementDrawableSpan extends ReplacementSpan {
14    protected Drawable mDrawable;
15    private final Paint mWorkPaint = new Paint();
16    private final Paint.FontMetricsInt mFontMetrics = new Paint.FontMetricsInt();
17    private float mExtraMargin;
18
19    public ReplacementDrawableSpan(Drawable drawable) {
20        super();
21        mDrawable = drawable;
22    }
23
24    public void setExtraMargin(float margin) {
25        mExtraMargin = margin;
26    }
27
28    private void setupFontMetrics(Paint.FontMetricsInt fm, Paint paint) {
29        mWorkPaint.set(paint);
30        if (fm != null) {
31            mWorkPaint.getFontMetricsInt(fm);
32
33            final Rect bounds = getBounds();
34            final int textHeight = fm.descent - fm.ascent;
35            final int halfMargin = (int) mExtraMargin / 2;
36            fm.ascent = Math.min(fm.top, fm.top + (textHeight - bounds.bottom) / 2) - halfMargin;
37            fm.descent = Math.max(fm.bottom, fm.bottom + (bounds.bottom - textHeight) / 2)
38                    + halfMargin;
39            fm.top = fm.ascent;
40            fm.bottom = fm.descent;
41        }
42    }
43
44    @Override
45    public int getSize(Paint paint, CharSequence text, int i, int i2, Paint.FontMetricsInt fm) {
46        setupFontMetrics(fm, paint);
47        return getBounds().right;
48    }
49
50    @Override
51    public void draw(Canvas canvas, CharSequence charSequence, int start, int end, float x, int top,
52                     int y, int bottom, Paint paint) {
53        setupFontMetrics(mFontMetrics, paint);
54
55        canvas.save();
56        int transY = (bottom - mDrawable.getBounds().bottom + top) / 2;
57        canvas.translate(x, transY);
58        mDrawable.draw(canvas);
59        canvas.restore();
60    }
61
62    protected Rect getBounds() {
63        return mDrawable.getBounds();
64    }
65}
66