安卓TextView字符串长度计算和字体大小自适应方法

之前在项目中遇到了测量字符串手机显示的宽度与高度的问题,最近也遇到同样的问题,故将相关的知识点积累如下:

  • 在View中draw一个字符串,如何获得字符串所占据的高度与宽度;
  • 在宽度固定的TextView中,如何自动缩小字体来适配TextView,使之刚好在这个TextView中显示完全;

1.自定义View中获取字符串的高度宽度
比如我现在自定义了一个MyView,我现在想在这个MyView中显示一个字符串,同时我想获取这个字符串的所占据的高度和宽度,示例代码如下:

/** 
 * @ClassName: MyView 
 * @Description: TODO
 * @author lixiasong
 * @date 2016-8-4 下午2:59:19 
 *  
 */
public class MyView extends View {

    private Paint mPaint ;
    /**
     * @param context
     * @param attrs
     */
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        init();
    }

    private void init()
    {
        //声明一个Paint
        mPaint = new Paint();

        //设置字体大小
        mPaint.setTextSize(20.0f);

        //用来测试的字符串
        String testString = "test string";
        /*
         * 根据 getTextBounds获取宽度和高度
         */
        Rect rec = new Rect();
        mPaint.getTextBounds(testString, 0, testString.length(), rec);
        //宽度
        int width1 = rec.right - rec.left;
        //高度
        int height1 = rec.bottom - rec.top ;

        /*
         * 根据 measureText获取宽度
         */
        float width2 = mPaint.measureText(testString);
    }
}

对于方法getTextBounds与measureText均能够获取到字符串的宽度,区别的话如下,其中红色的线为getTextBounds所测宽高度,粉红色线为measureText所测宽高度:
安卓TextView字符串长度计算和字体大小自适应方法_第1张图片

2.字符串大小自适应固定宽度TextView
在某些情况下我们的TextView的大小是固定的,我们希望不论多长的字符串,都能够自动调整大小来适应我们的TextView,示例代码如下:

/**
 * 
* @ClassName: MainActivity 
* @Description: TODO
* @author lixiasong
* @date 2016-8-4 下午3:19:17 
*
 */
public class MainActivity extends Activity {

    private TextView mTextView ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String testString = "this is a test string.";

        mTextView = (TextView)findViewById(R.id.textview1);

        //设置固定的宽高度
        mTextView.setWidth(100);
        mTextView.setHeight(300);
        mTextView.setText(testString);

        //设置计算好的字体大小
        mTextView.setTextSize(getTextSize(mTextView, 100, testString));
    }

    public float getTextSize(TextView tv , int w, String str)
    {
        //字符最大的大小
        float defaultSize = 40.0f;

        for(;;)
        {
            mTextView.setTextSize(defaultSize);
            Paint paint = mTextView.getPaint();
            float wm = paint.measureText(str);
            if(wm <= w)
                break;
            else
                //每次减小的步长
                defaultSize -= 0.1;
        }
        return defaultSize;
    }
}

这里需要注意的有两点:
(1) 当TextView已经存在的时候,我们不能像1中那样重新声明一个Paint,而是获取该TextView的Paint,即mTextView.getPaint();
(2) 每次textSize减小的步长,步长越小适配的越精准,但是循环的次数越多,消耗的时间越多,多大的步长需要根据实际情况来权衡。

若有不当之处,还请大家指出,谢谢。
参考:Paint类measureText与getTextBounds的区别

你可能感兴趣的:(安卓)