Tags
android, canvas, compound, compound drawables, custom-ui, drawable, getCompoundPaddingLeft, getCompoundPaddingRight, glyph, layout, mozilla, onDraw, onMeasure, optimization, optimize, paint, performance, text, view hierarchy
How can we use the same hack as Multiple Text Layout in some UI we need most of the times? Let’s take buttons for example. If we want the glyph in the button to be centered along with the text, we cannot use compound drawables — as they are always drawn along the edges of the container.
We could use our getCompoundPaddingLeft()
to pack the glyph with the text.
@Override public int getCompoundPaddingLeft() { // Ideally we should be overriding getTotalPaddingLeft(). // However, android doesn't make use of that method, // instead uses this method for calculations. int paddingLeft = super.getCompoundPaddingLeft(); paddingLeft += mDrawableWidth + getCompoundDrawablePadding(); return paddingLeft; }
This offsets the space on the left and Android will take care of placing the text accordingly. Now we can place the Drawable in the space we created.
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int paddingLeft = getPaddingLeft(); int paddingRight = getPaddingRight(); int drawableVerticalHeight = mDrawableHeight + getPaddingTop() + getPaddingBottom(); int width = getMeasuredWidth(); int height = Math.max(drawableVerticalHeight, getMeasuredHeight()); setMeasuredDimension(width, height); int compoundPadding = getCompoundDrawablePadding(); float totalWidth = mDrawableWidth + compoundPadding + getLayout().getLineWidth(0); float offsetX = (width - totalWidth - paddingLeft - paddingRight)/2.0f; mTranslateX = offsetX + paddingLeft; mTranslateY = (height - mDrawableHeight)/2.0f; }
The mTranslateX
and mTranslateY
are used to hold how far to translate to draw the drawable. Either the Drawable’s bounds can be shifted inside onMeasure()
to reflect the translation. Or, the Canvas can be translated inside onDraw()
. This will help us draw the glyph centered along with the text as a part of a Button!
creating objects in onMeasure… i hope its only for the purpose of the demo