TextView的字体大小在Android应用程序改变字体大小从本机设置

我想在我的应用程序中指定我自己的文本大小,但我这样做有一个问题。

当我在设备设置中改变字体大小时,我的应用程序TextView的字体大小也会改变。

636351 次浏览

实际上,设置字体大小只影响sp中的大小。所以所有你需要做的-在dp中定义textSize而不是sp,那么设置将不会改变应用程序中的文本大小。

下面是文档的链接:

但是请注意,预期的行为是所有应用程序中的字体都尊重用户的偏好。用户可能有很多原因想要调整字体大小,其中一些甚至可能是医疗视力受损的用户。使用dp而不是sp作为文本可能会导致不情愿地歧视应用程序的一些用户。

即:

android:textSize="32dp"

使用dimension类型的资源,就像使用string资源(文档)一样。

在你的dimens.xml文件中,声明你的维度变量:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="textview_height">25dp</dimen>
<dimen name="textview_width">150dp</dimen>
<dimen name="ball_radius">30dp</dimen>
<dimen name="font_size">16sp</dimen>
</resources>

然后你可以像这样使用这些值:

<TextView
android:layout_height="@dimen/textview_height"
android:layout_width="@dimen/textview_width"
android:textSize="@dimen/font_size"/>
你可以为不同类型的屏幕声明不同的dimens.xml文件。 这样做将确保你的应用在不同设备上呈现出理想的外观

当你不指定android:textSize时,系统使用默认值。

还要注意,如果在代码中设置了textSize,调用textView.setTextSize(X)将数字(X)解释为SP。使用setTextSize(TypedValue.COMPLEX_UNIT_DIP, X)dp中设置值。

最简单的方法就是使用如下代码:

android:textSize="32sp"

如果你想了解更多关于textSize属性的信息,你可以查看Android开发者文档. properties。

如果已经在dimension .xml文件中定义了DIP或SP,那么必须通过代码再次指定DIP或SP并不是一件好事。

我认为最好的选择是在使用dimension .xml值时使用PX:

tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.txt_size));

这样,如果需要,您可以在dimension .xml文件中从DP切换到SP,而无需更改任何代码。

这可能会有所帮助。将代码添加到您的自定义Application或BaseActivity中

/**
* 重写 getResource 方法,防止系统字体影响
*
* @return
*/
@Override
public Resources getResources() {
Resources resources = super.getResources();
if (resources != null && resources.getConfiguration().fontScale != 1) {
Configuration configuration = resources.getConfiguration();
configuration.fontScale = 1;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
return resources;
}

然而,Resource#updateConfiguration是在API级别25中部署的,这意味着在未来的某一天它将不受支持。

防止整个应用程序受到系统字体大小影响的简单方法是使用一个基本活动updateConfiguration。

//in base activity add this code.
public  void adjustFontScale( Configuration configuration) {


configuration.fontScale = (float) 1.0;
DisplayMetrics metrics = getResources().getDisplayMetrics();
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
metrics.scaledDensity = configuration.fontScale * metrics.density;
getBaseContext().getResources().updateConfiguration(configuration, metrics);


}


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adjustFontScale( getResources().getConfiguration());
}

如果使用的单位是SP,而不是DP,并且你想重写系统字体缩放,你所要做的就是重写activity中的一个方法——请看这篇文章

resources.updateConfiguration已弃用和bug(在Oreo上,我有格式化文本的问题)。

你可以使用下面的代码:

android:textSize="32dp"
它解决了你的问题,但你必须知道你应该尊重用户的决定。 这样,从设备设置中更改文本大小不会更改此值。所以这就是为什么你需要使用sp而不是dp。 所以我的建议是使用不同的系统字体大小(小,正常,大,…)

< a href = " https://stacklearn。Ir " rel="nofollow noreferrer">https://stacklearn.ir

在Activity中覆盖getResources()

设置TextView的大小在sp通常像android:textSize="32sp"

override fun getResources(): Resources {
return super.getResources().apply {
configuration.fontScale = 1F
updateConfiguration(configuration, displayMetrics)
}
}

对于kotlin,这对我来说是有效的

priceTextView.textSize = 12f

将DP更改为sp,这是android的良好实践 android: textSize = " 18 sp " < / p >

在android 8中,这个解决方案适合我

在基本活动中添加此代码

@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
final Configuration override = new Configuration(newBase.getResources().getConfiguration());
override.fontScale = 1.0f;
applyOverrideConfiguration(override);
}
< p >源 https://stackoverflow.com/a/57225687/7985871 < / p >

这个解决方案是使用Kotlin,并且不使用已弃用的函数资源

    override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
adjustFontScale(resources.configuration)
}


private fun adjustFontScale(configuration: Configuration?) {
configuration?.let {
it.fontScale = 1.0F
val metrics: DisplayMetrics = resources.displayMetrics
val wm: WindowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
wm.defaultDisplay.getMetrics(metrics)
metrics.scaledDensity = configuration.fontScale * metrics.density


baseContext.applicationContext.createConfigurationContext(it)
baseContext.resources.displayMetrics.setTo(metrics)


}
}

观察:这是与以上相同的解决方案,但与Kotlin进行了udpated

我通常在资源文件中改变大小

<resources>
<dimen name="siez_1">40px</dimen>
<dimen name="siez_2">50px</dimen>
<dimen name="siez_3">60px</dimen>


</resources>