1. 程式人生 > 實用技巧 >android開發 textview根據字數長度自動調整字型大小

android開發 textview根據字數長度自動調整字型大小

import com.carspeak.client.util.DensityUtils;
 
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;
 
public class
ShadowTextView extends TextView { private static float DEFAULT_MIN_TEXT_SIZE = 10; private static float DEFAULT_MAX_TEXT_SIZE = 85; // Attributes private Paint testPaint; private float minTextSize, maxTextSize; private String TAG = "ShadowTextView"; public ShadowTextView(Context context, AttributeSet attrs) {
super(context, attrs); initialise(); } public ShadowTextView(Context context) { super(context); } public ShadowTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onTextChanged(CharSequence text, int
start,int lengthBefore, int lengthAfter) { super.onTextChanged(text, start, lengthBefore, lengthAfter); refitText(text.toString(), this.getWidth(),this.getHeight()); } private void initialise() { testPaint = new Paint(); testPaint.set(this.getPaint()); // max size defaults to the intially specified text size unless it is // too small maxTextSize = this.getTextSize(); if (maxTextSize <= DEFAULT_MAX_TEXT_SIZE) { maxTextSize = DEFAULT_MAX_TEXT_SIZE; } minTextSize = DEFAULT_MIN_TEXT_SIZE; }; @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w != oldw) { // refitText(this.getText().toString(), w); //原本是需要執行的 } } /** * 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,int textHeight) { int Length = text.length(); //直接根據字元長度來調整字型大小 最大長度為20 // this.setTextSize(DensityUtils.dp2px(this.getContext(), trySize)); // testPaint.set(this.getPaint()); if (textWidth > 0) { int availableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); //獲取改TextView的畫布可用大小 float trySize = maxTextSize; float scaled = getContext().getResources().getDisplayMetrics().scaledDensity; // Log.v(TAG, "availableWidth="+availableWidth + ";scaled="+scaled); testPaint.setTextSize(trySize*scaled); //模擬 注意乘以scaled while ((trySize > minTextSize)&& (testPaint.measureText(text) > availableWidth)) { trySize -= 2; FontMetrics fm = testPaint.getFontMetrics(); double rowFontHeight = (Math.ceil(fm.descent - fm.top) + 2); float scaled1 = (float) (this.getHeight() /rowFontHeight ); //字型的行數 textview的總高度/每行字的高度 float scaled2 = (float) ((testPaint.measureText(text) / availableWidth)); //也是行數 所有字的總長度/textview的有效寬度 // Log.v(TAG, "trySize="+trySize + ";testPaint.measureText(text)="+testPaint.measureText(text)+";scaled1="+scaled1+";scaled2="+scaled2+";rowFontHeight="+rowFontHeight); if((scaled2*rowFontHeight*1.9)<this.getHeight()) //1.9代表是1.9的行高(1個字型本身,0.9的行距 ,大致差不多,沒有實際測過) break; if (trySize <= minTextSize) { trySize = minTextSize; break; } testPaint.setTextSize(trySize*scaled); } this.setTextSize(trySize); // Log.v(TAG, "trySize="+trySize+";maxTextSize="+maxTextSize+";minTextSize="+minTextSize); } } // private void refitText(String text, int textWidth,int textHeight) { //// if (textWidth > 0) { //// int availableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); //獲取改TextView的畫布可用大小 //// float trySize = maxTextSize; //// float scaled = getContext().getResources().getDisplayMetrics().scaledDensity; //// testPaint.setTextSize(trySize*scaled); //模擬 注意乘以scaled //// while ((trySize > minTextSize)&& (testPaint.measureText(text) > availableWidth)) { //// trySize -= 2; //// FontMetrics fm = testPaint.getFontMetrics(); //// float scaled1 = (float) (this.getHeight() / (Math.ceil(fm.descent - fm.top) + 2)); //// float scaled2 = (float) ((testPaint.measureText(text) / availableWidth)); //// if (scaled1 >= 1.75 & scaled1 >= scaled2) { // 注意1.75是三星s4 小米3 的適合數值(當然包括我的聯想了) //// break; //// } //// if (trySize <= minTextSize) { //// trySize = minTextSize; //// break; //// } //// testPaint.setTextSize(trySize*scaled); //// } //// this.setTextSize(trySize); //等同於this.getPaint().set(trySize*scaled); //// } // } }

使用:(注意不能給預設字型大小,否則有問題)

<com.view.ShadowTextView
                    android:id="@+id/tv_shadow_preview"
                    android:layout_width="@dimen/projection_screen_width_4_3"
                    android:layout_height="@dimen/projection_screen_height_4_3"
                    android:layout_centerHorizontal="true"
                    android:background="#000"
                    android:text="字幕"
                    android:gravity="center"
                    android:textColor="#fff" />

Android的TextView控制元件會在文字上下加上預設的padding值,該值隨著文字大小成正比變化,只要為TextView設定android:includeFontPadding=”false”;就可以減少大部分上下空白,而且如果文字sp值小,也就看不出空白了