package com.mygeopay.wallet.ui.widget;
import android.content.Context;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Based on
* http://stackoverflow.com/questions/2617266/how-to-adjust-text-font-size-to-fit-textview?answertab=votes#tab-top
*/
public class FontFitTextView extends TextView {
private static final Logger log = LoggerFactory.getLogger(FontFitTextView.class);
//Attributes
private float maxTextSize;
private Paint mTestPaint;
public FontFitTextView(Context context) {
super(context);
initialise();
}
public FontFitTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initialise();
}
private void initialise() {
mTestPaint = new Paint();
mTestPaint.set(this.getPaint());
maxTextSize = getTextSize();
//max size defaults to the initially specified text size unless it is too small
}
/* Re size the font so the specified text fits in the text box
* assuming the text box is the specified width.
*/
private void refitText(String text, int textWidth)
{
if (textWidth <= 0)
return;
int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
float hi = maxTextSize;
float lo = 10;
final float threshold = 0.5f; // How close we have to be
mTestPaint.set(this.getPaint());
while((hi - lo) > threshold) {
float size = (hi+lo)/2;
mTestPaint.setTextSize(size);
if(mTestPaint.measureText(text) >= targetWidth)
hi = size; // too big
else
lo = size; // too small
}
// Use lo so that we undershoot rather than overshoot
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
refitText(this.getText().toString(), parentWidth);
this.setMeasuredDimension(parentWidth > width ? width : parentWidth, height);
}
@Override
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, maxTextSize);
}
@Override
public void setTextSize(float size) {
log.error("Use setMaxTextSize instead");
}
@Override
public void setTextSize(int unit, float size) {
log.error("Use setMaxTextSize instead");
}
@Override
/** {@inheritDoc} */
public void setText(CharSequence text, BufferType type) {
final String DOUBLE_BYTE_WORDJOINER = "\u2060";
String fixString = "";
/* bug workaround https://code.google.com/p/android/issues/detail?id=17343#c9 */
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR1
&& android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
fixString = DOUBLE_BYTE_WORDJOINER;
}
super.setText(text + fixString, type);
}
/**
* Set the max size (in pixels) of the default text size in this TextView.
*/
public void setMaxTextSize(float maxTextSize) {
this.maxTextSize = maxTextSize;
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, maxTextSize);
}
/**
* Get the max size (in pixels) of the default text size in this TextView.
*/
public float getMaxTextSize() {
return maxTextSize;
}
}