场景一:

开发中经常会遇到这样的情况,某天你心情正好的时候,产品拿着某台设备跑过来告诉你,快看这里的文字显示不下了,开发会说:擦,你这个字太长了啊,当然就显示不下了。然后产品会说:你看iOS是好的,看起来当文字太多的时候,字体变小了。之后Android开发就跑去问iOS开发你这个是怎么做到的,答曰:系统自带的功能,当显示不下时会自动缩小字号。Android开发表示心好累啊,如图:

配置文件:

android:id="@+id/tv"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="100dp"
android:singleLine="true"
android:text="Hello World! 字体大小自适应的TextView" />
如上所示发现字体太长默认...
解决方案
private void adjustTvTextSize(TextView tv, int maxWidth, String text) {
int avaiWidth = maxWidth - tv.getPaddingLeft() - tv.getPaddingRight() - 10;
if (avaiWidth <= 0) {
return;
}
TextPaint textPaintClone = new TextPaint(tv.getPaint());
// note that Paint text size works in px not sp
float trySize = textPaintClone.getTextSize();
while (textPaintClone.measureText(text) > avaiWidth) {
trySize--;
textPaintClone.setTextSize(trySize);
}
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}

调用如上方法展示效果如下:

当文本过长字体自动缩小,智能适配,宝宝好苦,宝宝不说。

场景二:数据科学家

做个简单的例子,先验证一下:

同样的布局代码

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="Hello World! in SP" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="Hello World! in DP" />

调节设置中显示字体大小

运行后显示样式

回到标题要解决的问题,如果要像微信一样,所有字体都不允许随系统调节而发生大小变化,要怎么办呢?利用Android的Configuration类中的fontScale属性,其默认值为1,会随系统调节字体大小而发生变化,如果我们强制让其等于默认值,就可以实现字体不随调节改变,在工程的Application或BaseActivity中添加下面的代码:

解决方案:

@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig.fontScale != 1)//非默认值
getResources();
super.onConfigurationChanged(newConfig);
}
@Override
public Resources getResources() {
Resources res = super.getResources();
if (res.getConfiguration().fontScale != 1) {//非默认值
Configuration newConfig = new Configuration();
newConfig.setToDefaults();//设置默认
res.updateConfiguration(newConfig, res.getDisplayMetrics());
}
return res;
}

总结:

一是布局宽高固定的情况下,字体单位改用dp表示;

二是通过3中的代码设置应用不能随系统调节,在检测到fontScale属性不为默认值1的情况下,强行进行改变。