1. 程式人生 > >Android動態更改TextView的字型大小

Android動態更改TextView的字型大小

需求:

需要動態更改TextView內容字型的大小,比如設定TextView只有一行,寬度只有200dp,內容超過這個之後就縮小字型顯示,只能能將字型都顯示完全;也就是動態更改TextView的字型大小,當TextView的內容比較多時縮小顯示,當TextView的內容比較少時正常顯示。

使用方式詳見官網介紹。

例子展示:

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

可以看出來:當文字沒有填充TextView完全時顯示的就是預設的字型,當文字能夠完全填充TextView並且一行顯示不下時,他會預設的縮小文字的字型,當文字再多時,他會預設在末尾省略。

AutofitTextView.java程式碼:

package
me.grantland.widget; import android.content.Context; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.TextView; /** * A {@link TextView} that re-sizes its text to be no larger than the width of the view. * * @attr ref R.styleable.AutofitTextView_sizeToFit * @attr
ref R.styleable.AutofitTextView_minTextSize * @attr ref R.styleable.AutofitTextView_precision */
public class AutofitTextView extends TextView implements AutofitHelper.OnTextSizeChangeListener { private AutofitHelper mHelper; public AutofitTextView(Context context) { super(context); init(context, null
, 0); } public AutofitTextView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs, 0); } public AutofitTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs, defStyle); } private void init(Context context, AttributeSet attrs, int defStyle) { mHelper = AutofitHelper.create(this, attrs, defStyle) .addOnTextSizeChangeListener(this); } // Getters and Setters /** * {@inheritDoc} */ @Override public void setTextSize(int unit, float size) { super.setTextSize(unit, size); if (mHelper != null) { mHelper.setTextSize(unit, size); } } /** * {@inheritDoc} */ @Override public void setLines(int lines) { super.setLines(lines); if (mHelper != null) { mHelper.setMaxLines(lines); } } /** * {@inheritDoc} */ @Override public void setMaxLines(int maxLines) { super.setMaxLines(maxLines); if (mHelper != null) { mHelper.setMaxLines(maxLines); } } /** * Returns the {@link AutofitHelper} for this View. */ public AutofitHelper getAutofitHelper() { return mHelper; } /** * Returns whether or not the text will be automatically re-sized to fit its constraints. */ public boolean isSizeToFit() { return mHelper.isEnabled(); } /** * Sets the property of this field (sizeToFit), to automatically resize the text to fit its * constraints. */ public void setSizeToFit() { setSizeToFit(true); } /** * If true, the text will automatically be re-sized to fit its constraints; if false, it will * act like a normal TextView. * * @param sizeToFit */ public void setSizeToFit(boolean sizeToFit) { mHelper.setEnabled(sizeToFit); } /** * Returns the maximum size (in pixels) of the text in this View. */ public float getMaxTextSize() { return mHelper.getMaxTextSize(); } /** * Set the maximum text size to the given value, interpreted as "scaled pixel" units. This size * is adjusted based on the current density and user font size preference. * * @param size The scaled pixel size. * * @attr ref android.R.styleable#TextView_textSize */ public void setMaxTextSize(float size) { mHelper.setMaxTextSize(size); } /** * Set the maximum text size to a given unit and value. See TypedValue for the possible * dimension units. * * @param unit The desired dimension unit. * @param size The desired size in the given units. * * @attr ref android.R.styleable#TextView_textSize */ public void setMaxTextSize(int unit, float size) { mHelper.setMaxTextSize(unit, size); } /** * Returns the minimum size (in pixels) of the text in this View. */ public float getMinTextSize() { return mHelper.getMinTextSize(); } /** * Set the minimum text size to the given value, interpreted as "scaled pixel" units. This size * is adjusted based on the current density and user font size preference. * * @param minSize The scaled pixel size. * * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize */ public void setMinTextSize(int minSize) { mHelper.setMinTextSize(TypedValue.COMPLEX_UNIT_SP, minSize); } /** * Set the minimum text size to a given unit and value. See TypedValue for the possible * dimension units. * * @param unit The desired dimension unit. * @param minSize The desired size in the given units. * * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize */ public void setMinTextSize(int unit, float minSize) { mHelper.setMinTextSize(unit, minSize); } /** * Returns the amount of precision used to calculate the correct text size to fit within its * bounds. */ public float getPrecision() { return mHelper.getPrecision(); } /** * Set the amount of precision used to calculate the correct text size to fit within its * bounds. Lower precision is more precise and takes more time. * * @param precision The amount of precision. */ public void setPrecision(float precision) { mHelper.setPrecision(precision); } @Override public void onTextSizeChange(float textSize, float oldTextSize) { // do nothing } }

原理:

AutofitTextView:自定義TextView並繼承系統的TextView,然後在繪製元件的時候根據getMaxLines方法獲取內容的行數若內容的行數大於1,則縮小文字的字型,然後在嘗試獲取getMaxLines方法,若內容的行數還是大於1,則縮小文字的字型,直到內容能夠一行顯示或者是字型縮小大一定的大小,這時候若縮小到一定的大小還是不能一行顯示,則尾部省略。

延伸:
TextView原始碼中:

public void setTextSize(float size) {
        setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
    }
public void setTextSize(int unit, float size) {
        Context c = getContext();
        Resources r;

        if (c == null)
            r = Resources.getSystem();
        else
            r = c.getResources();

        setRawTextSize(TypedValue.applyDimension(
                unit, size, r.getDisplayMetrics()));
    }

setTextSize(int unit, int size)
第一個引數可設定如下靜態變數:
TypedValue.COMPLEX_UNIT_PX : Pixels
TypedValue.COMPLEX_UNIT_SP : Scaled Pixels
TypedValue.COMPLEX_UNIT_DIP : Device Independent Pixels

我們在使用TextView控制元件時,呼叫setTextSize方法,預設就是以sp為單位,與xml配置檔案預設儲存一致。