Android 解决系统字体大小设置引起的布局混乱问题

解决方法

在 activity 内重写getResources方法(Fragment中的界面也会生效),如此在 xmljava 代码使用 sp 字体单位都是正常的。一般在BaseActivity内重写。

Java写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 设置 app 字体不随系统字体设置改变
*/
@Override
public Resources getResources() {
Resources res = super.getResources();
if (res != null) {
Configuration config = res.getConfiguration();
if (config != null && config.fontScale != 1.0f) {
config.fontScale = 1.0f;
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
return res;
}

Kotlin写法

1
2
3
4
5
6
7
8
9
10
11
override fun getResources(): Resources {
val res = super.getResources()
if (res != null) {
val config = res.configuration
if (config != null && config.fontScale !== 1.0f) {
config.fontScale = 1.0f
res.updateConfiguration(config, res.displayMetrics)
}
}
return res
}

注意!网上很多地方写着使用config.setToDefaults();,实际上除了影响 app 内字体大小,还会影响很多地方的属性值。我们来看一下源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Set this object to the system defaults.
*/
public void setToDefaults() {
fontScale = 1;
mcc = mnc = 0;
mLocaleList = LocaleList.getEmptyLocaleList();
locale = null;
userSetLocale = false;
touchscreen = TOUCHSCREEN_UNDEFINED;
keyboard = KEYBOARD_UNDEFINED;
keyboardHidden = KEYBOARDHIDDEN_UNDEFINED;
hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
navigation = NAVIGATION_UNDEFINED;
navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
screenLayout = SCREENLAYOUT_UNDEFINED;
uiMode = UI_MODE_TYPE_UNDEFINED;
screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
densityDpi = DENSITY_DPI_UNDEFINED;
seq = 0;
}

因此,我们只需要把fontScale属性值设置成默认值1即可。