在app的开发过程中可能很多人都会遇到这样的一个问题,当你把手机系统的字体大小改变之后再次进入我们的app时候,app的界面简直是惨不忍睹,进过网上查询资料,发现出现在介绍时候我们必须把px dp sp这三个单位理解清楚:
PX:px就是pixel的缩写啦,pixel即像素,它不是自然界的长度单位。px是就是一张图片中最小的点,一张位图就是由这些点构成的。1024px就是1024像素,最简单的你可以在windows桌面属性里的“设置”看到,如果是1024×768,也就是说水平方向上有1024个点,垂直方向上有768个点。谁能说出一个“点”有多长多大么?可以画的很小,也可以很大。如果点很小,那画面就清晰,我们称它为“分辨率高”,反之,就是“分辨率低”。所以,像素的大小是会“变”的,也称为“相对长度”。
在编程的过程种一般是不会使用px的,因为android手机的种类太多了,尺寸大小不一。
DP:与密度无关的像素,这是一个基于屏幕物理密度的抽象单位。
正是因为android尺寸太多的变化,px无法正常的显示,Android为我们提供了一个虚拟的像素单位 - DP 或者 DIP (Density-Independent pixel),当然也可以理解为 Device-Independent Pixel。为什么说是虚拟呢,因为它的大小不是一个物理(Phisical)值,而是由操作系统根据屏幕大小和密度动态渲染出来的,正是因为如此,dp设置的大小在不同的手机中使用是相同的。
SP:SP 全称是 Scale-independent Pixels,用于字体大小,其概念与DP是一致的,也是为了保持设备无关。因为Android用户可以根据喜好来调整字体大小,所以要使用sp来表示字体大小。
看了sp px dp的解释之后大概就会明白这个问题出现的原因了。因为我们在设置textview的字体大小的时候,我们在布局文件中一般都会使用dp,但是我们在代码中设置字体大小的时候使用代码:
tv_sp.setTextSize(20);
字体设置了,可我们并不知道设定的25到底是多大的,单位会是像素(px)吗?其实不是像素(px),而是缩放像素sp(scaled pixel),官方对SetTextSize的说明也是非常清楚的
Set the default text size to the given value, interpreted as “scaled pixel” units. This size is adjusted based on the current density and user font size preference.
那使用代码设置的字体单位只能是sp了吗?其实也不是,Android还有一个setTextSize的重载方法,可以通过设置单位了来限定字体的大小
tv_sp.setTextSize(TypedValue.COMPLEX_UNIT_PX,20); //22像素
tv_sp.setTextSize(TypedValue.COMPLEX_UNIT_SP,20); //22SP
tv_sp.setTextSize(TypedValue.COMPLEX_UNIT_DIP,20);//22DIP
这样,在代码中设置字体大小时,同时将字体大小的单位设置了dp,就可以固定字体大小不随系统设定的字号变化了。
但是可能在写完代码之后才发现,自己都不知道具体的设置字体在哪里了。 针对该设置,影响的是Configuration下的fontScale,所以我们只需要重写getResources,去设置fontScale就可以了。
Configuration conf = getResources().getConfiguration();
Log.e("TestTAG" , "fontScale=" + conf.fontScale);
我们只需要在基类BaseActivity或者Application(这里设置之后,后面需要修改就不好设置了)里面设置下面的代码就可以了:
@Override
public Resources getResources() {
Resources res = super.getResources();
Configuration config=new Configuration();
config.setToDefaults();
res.updateConfiguration(config,res.getDisplayMetrics() );
return res;
}
但是其实google设置这个也是有原因的,主要给中老年人使用时候字体的改变,例如在网页浏览时候,改变字体大小可以更好的让人浏览,那么我们在使用的时候不要去继承BaseActivity重新继承Activity去编码。
没有重写getresouces时候设置的dp和sp的显示:
设置getresouces之后字体不再跟随系统改变了:
在网上还看到很多人说点击Home出去之后,更改字体大小再次进入app的时候,字体还是会改变大小(在重写getResouces的前提下),但是我这边测试是没有问题的,如果有问题的话,我们可以在onresume()中把getResouces()重写一遍就可以了。
如果在application中重写了getResouces怎么恢复跟随系统字体改变呢?我直接再次重写 返回 super.getResouces()还是没法恢复变化。
欢迎大家指点。