动态更新字体大小以适应组件宽度

阅读更多

起始需求是TextView能够根据自身宽度自动调整字体大小,有以下链接可以参考

Auto Scale TextView Text to Fit within Bounds

Auto-fit TextView for Android

Using auto resize to fit EditText in Android (该文章列出了一些github的项目)

只是在我的项目中表现并不好。

 

于是考虑自己在代码中通过循环的方式,递减以达到字体大小自适应的效果。

该方法有几个要点:

1. dp <--> px,sp <--> px之间的转换

 

/**
 * 将px值转换为dp值
 */
public static float px2dp(final Context context, final float px) {
    return px / context.getResources().getDisplayMetrics().density;
}

/**
 * 将dp值转换为px值
 */
public static float dp2px(final Context context, final float dp) {
    return dp * context.getResources().getDisplayMetrics().density;
}

/**
 * 将px值转换为sp值,保证文字大小不变
 */
public static int px2sp(Context context, float pxValue) {
    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
    return (int) (pxValue / fontScale + 0.5f);
}

/**
 * 将sp值转换为px值,保证文字大小不变
 */
public static int sp2px(Context context, float spValue) {
    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
    return (int) (spValue * fontScale + 0.5f);
}

 

2. 获取控件自身的大小

通过getWidth(in px),或者如gridview,通过 (总宽度-margin-padding)/column 的方式获取,此处命名为itemWidth。

 

3. 字符串在view中占据空间的计算

参考 How to calculate string font width in pixels

Paint paint = new Paint();

//参数以px为单位
paint.setTextSize(sizeInPX);

//得到的结果也是以px为单位
float cursize = paint.measureText(textContent);

 

4. 循环寻找适配大小

Paint paint = new Paint();

int defaultFontSize = 16; //in sp

int finalTextSize = defaultFontSize;

String content="anything for test";

paint.setTextSize(sp2px(this, defaultFontSize));

float cursize = paint.measureText(content);

// finalTextSize > defaultFontSize/2 这样的限制按需修改
while (cursize > itemWidth && finalTextSize > defaultFontSize/2) {
    finalTextSize -= 1;

    Log.w(TAG, "has to change # " + content + " font size # " + finalTextSize);

    paint.setTextSize(sp2px(this, realTextSize));
    cursize = paint.measureText(content);
}

//现在最终的字体大小已经获取
//此处以textview为例
//需要注意textView setTextSize是以sp为单位的
textView.setTextSize(realTextSize);

//如果需要设置padding,那么相应的itemWidth也应该做调整
//textView.setPadding(horizontalMargin, 0, horizontalMargin, 0);

textView.setGravity(Gravity.CENTER);
...

 

 

 

 

你可能感兴趣的:(自适应,宽度,字体)