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值小,也就看不出空白了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM