Android中App控制字体大小
Posted 巨头之路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中App控制字体大小相关的知识,希望对你有一定的参考价值。
android中App字体不随系统字体大小的改变而改变
通常是在Application或Activity中复写getResources方法 ,下面的代码就实现了app字体不随系统字体大小改变.
override fun getResources(): Resources
val res = super.getResources()
if(res != null && res.configuration.fontScale != 1f)
val config = res.configuration
config.setToDefaults()
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 )
createConfigurationContext(config)
else
res.updateConfiguration(config, res.displayMetrics)
return super.getResources()
还可以将textView的单位设置为dp,这样也不会跟随系统字体大小改变,但是这里有个不好的地方,如果app中要求可以调节app全局的字体大小功能,这时候用dp作为单位就不太好了.
一般上面重写getResources函数,是在app启动的时候才会生效,假设app在运行的时候~用户跑去系统设置里更改字体大小,这时候上面的配置不就不会生效了,而app里的文字会跟着系统设置的字体大小而改变. 怎么解决呢? 重写Application的onConfigurationChanged函数做监听操作,当系统字体大小发生变化,会触发这个函数的调用,所以可以在该函数内重启应用或主Activity,使得上面的getResources会被调用,从而app里的文字不就不会跟着系统设置的字体大小而改变
@Override
public void onConfigurationChanged(Configuration newConfig)
if(newConfig.fontScale > 1)
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
super.onConfigurationChanged(newConfig);
遇到的问题:
-
在Android7.0中,调用Configuration类的setToDefaults函数,会使得Dialog弹框不显示(半透明背景显示),这是因为在Android7.0中,Configuration类的setToDefaults函数内将screenWidthDp和screenHeightDp都置为0 (SCREEN_WIDTH_DP_UNDEFINED和SCREEN_HEIGHT_DP_UNDEFINED的值都为0), 从而造成dialog显示不了,怎么解决? 不调用setToDefaults函数,而单独设置Configuration类的属性,例如需要设置fontScale,代码如下
override fun getResources(): Resources val res = super.getResources() if(res != null && res.configuration.fontScale != 1f) val config = res.configuration config.fontScale = 1f if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 ) createConfigurationContext(config) else res.updateConfiguration(config, res.displayMetrics) return super.getResources()
-
在Android7.x中,重写getResources并不能使得app里的文字不会跟着系统设置的字体大小而改变,需要重写activity的attachBaseContext才能生效,代码如下
override fun attachBaseContext(newBase: Context?) if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) val res = newBase?.getResources() val config = res?.configuration config?.fontScale = 1 val newContext = newBase?.createConfigurationContext(config) super.attachBaseContext(newContext) return super.attachBaseContext(newBase)
app中要求可以调节app全局的字体大小功能实现
通过设置configuration类的fontScale来控制字体的缩放比例,从而实现app全局的字体大小控制. 建议一般标准字体按照 “1” 这个值来取,大字体可以设置为1.3.
fun setFontScale(fontScale: Float)
val res = resources
val configuration = res.configuration
configuration.fontScale = fontScale
res.updateConfiguration(configuration, res.displayMetrics)
注意:通过代码取当前页面textView,其字体大小值的单位是px,需要转化为sp,才能乘以上面的fontScale,从而拿到放大之后的字体大小值
Autosizing TextViews
当app文字大小需要根据系统文字大小,或app中设置fontScale值进行调整时,可能会导致TextView文字溢出,部分不能显示的问题,因为TextView是无法根据字体大小来动态控制宽高的,所以这时候Android8.0新增用来动态改变TextView字体大小的新特性 Autosizing TextViews 就上场了,Autosizing TextViews使得TextView可以动态调整其文字的大小,使得不会出现溢出或部分显示这种问题.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<TextView
android:layout_width="340dp"
android:layout_height="50dp"
android:background="@drawable/shape_bg_008577"
android:gravity="center_vertical"
android:maxLines="1"
android:text="Autosizing TextViews 用来动态改变TextView字体大小"
android:textSize="18sp"
android:autoSizeTextType="uniform"
android:autoSizeMaxTextSize="18sp"
android:autoSizeMinTextSize="10sp"
android:autoSizeStepGranularity="1sp"/>
</LinearLayout>
主要通过上面4个auto开头的属性来控制,具体属性意义自行查阅官方文档.当需要兼容8.0以下设备,则需要用AppCompatTextView代替TextView,并且上面几个属性的命名空间需要用app命名空间.
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen_size_30"
android:text="Autosizing TextViews 用来动态改变TextView字体大小"
app:autoSizeTextType="uniform"
app:autoSizeMaxTextSize="@dimen/textsize_16"
app:autoSizeMinTextSize="@dimen/textsize_12"
android:autoSizeStepGranularity="@dimen/textsize_2"/>
注意: 在AppCompatTextView使用android命名空间的auto开头的属性," 动态改变TextView字体大小 " 无效果
以上是关于Android中App控制字体大小的主要内容,如果未能解决你的问题,请参考以下文章