多分辨率适配—字体大小适配 sp与dp区别
一般方式:用values-XXXX的方式适配
但为什么字体要用sp而不直接用dp
如dp适配得好的话,而字体也可以用dp,sp和dp有什么区别?
首先,sp与dp最终都是转换成px在屏幕上显示的,而它们的转换出来大小不一样的话,说明它们的转换的方式不一样。
于是查看TextView设置字体大小的方法,然后追综到一个将xml中配置的字体大小转换的方法,源码如下:
TypedValue. applyDimension(int unit, float value, DisplayMetrics metrics)
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
很明显看到字体大小转换px时,对于dp是value * metrics.density,而sp是value * metrics.scaledDensity;
这样已经明白sp与dp为什么可以适屏不一样了,它们转换成px时,缩放参数不一样。
但是奇怪的是,为什么对于字体大小的适屏要额外处理,并且那个metrics.scaledDensity为什么不与metrics.density保持一致。
然后在开发者指引的一句话中令我惚然大悟。
Similarly, you should prefer the sp (scale-independent pixel) to define text sizes. The sp scale factor depends on a user setting and the system scales the size the same as it does for dp.
原来字体的缩放参数是可以被调整的,通过手机的系统设置—>显示—>字体大小你可以设置字体的缩放参数(听说是4.0或以上手机才有的),然后有四种选择,小、中、大、超大。对于字体sp的缩放的额外处理设计者大概是考虑到有的用户视力不好或者偏好于某种字体大小。
这样总的来说关于字体大小应该用sp好还是dp好呢?我觉得应该像文档说的,一般来说应该使用sp,因为这个是对于用户友好的,但是某些情况下,可以权衡一下实际情况,采用dp,譬如说设计师比较看重界面的一致性,不希望由于用户改了字体大小而严重破坏了界面美感。
关于sp与dp的选择的建议是:
1、 如果TextView的显示区域可以弹性变化(wrap_content,当然其所有父view也需要可以弹性变化),这时可以优先考虑用sp,这时字体大小更改一般来说不会破坏界面的可用性
2、 与1情况相反时,TextView的显示区域已经限定在一个固定值(或者其父view被限定了),这时优先考虑用dp吧,不然遇到一直使用着超大字体的用户,字体可能横向被截了,而用户不知情,会觉得是程序问题。
一般方式:用values-XXXX的方式适配
但为什么字体要用sp而不直接用dp
如dp适配得好的话,而字体也可以用dp,sp和dp有什么区别?
首先,sp与dp最终都是转换成px在屏幕上显示的,而它们的转换出来大小不一样的话,说明它们的转换的方式不一样。
于是查看TextView设置字体大小的方法,然后追综到一个将xml中配置的字体大小转换的方法,源码如下:
TypedValue. applyDimension(int unit, float value, DisplayMetrics metrics)
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
很明显看到字体大小转换px时,对于dp是value * metrics.density,而sp是value * metrics.scaledDensity;
这样已经明白sp与dp为什么可以适屏不一样了,它们转换成px时,缩放参数不一样。
但是奇怪的是,为什么对于字体大小的适屏要额外处理,并且那个metrics.scaledDensity为什么不与metrics.density保持一致。
然后在开发者指引的一句话中令我惚然大悟。
Similarly, you should prefer the sp (scale-independent pixel) to define text sizes. The sp scale factor depends on a user setting and the system scales the size the same as it does for dp.
原来字体的缩放参数是可以被调整的,通过手机的系统设置—>显示—>字体大小你可以设置字体的缩放参数(听说是4.0或以上手机才有的),然后有四种选择,小、中、大、超大。对于字体sp的缩放的额外处理设计者大概是考虑到有的用户视力不好或者偏好于某种字体大小。
这样总的来说关于字体大小应该用sp好还是dp好呢?我觉得应该像文档说的,一般来说应该使用sp,因为这个是对于用户友好的,但是某些情况下,可以权衡一下实际情况,采用dp,譬如说设计师比较看重界面的一致性,不希望由于用户改了字体大小而严重破坏了界面美感。
关于sp与dp的选择的建议是:
1、 如果TextView的显示区域可以弹性变化(wrap_content,当然其所有父view也需要可以弹性变化),这时可以优先考虑用sp,这时字体大小更改一般来说不会破坏界面的可用性
2、 与1情况相反时,TextView的显示区域已经限定在一个固定值(或者其父view被限定了),这时优先考虑用dp吧,不然遇到一直使用着超大字体的用户,字体可能横向被截了,而用户不知情,会觉得是程序问题。