从文档:https ://developer.android.com/training/multiscreen/screendensities
要在不同密度的屏幕上保持 UI 的可见尺寸,您必须使用与密度无关的像素 (dp) 作为度量单位来设计 UI。一 dp 是一个虚拟像素单位,大致等于中等密度屏幕(160dpi;“基线”密度)上的一个像素。
因此,dp 的整个想法是指定一个独立于屏幕密度的度量。
但是,在定义文本大小时,您应该改用可缩放像素 (sp) 作为单位(但不要使用 sp 作为布局大小)。默认情况下,sp 单位的大小与 dp 相同,但它会根据用户的首选文本大小调整大小。
这里的想法是,如果用户有视力障碍,他可以通过改变系统设置来改变文本的大小。另请注意sp 单位的大小与 dp 相同:系统设置为文本的默认大小,dp 和 sp 之间没有区别。所以你不应该看到改变 sp 和 dp 之间的布局大小有任何区别。两者都将转换为相同数量的像素。
但从不使用 sp 作为布局大小的原因仅仅是您不希望图像、按钮或任何其他布局维度根据文本大小的系统偏好进行缩放。这对我来说似乎很明显。
辅助功能设置: https: //support.google.com/accessibility/android/answer/6006972
Android OS 上将不同单位转换为像素的代码是:(来自https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/android/util/TypedValue。爪哇)
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;
}
以及解释什么是 scaledDensity 的评论:(来自https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util/DisplayMetrics.java)
/**
* A scaling factor for fonts displayed on the display. This is the same
* as {@link #density}, except that it may be adjusted in smaller
* increments at runtime based on a user preference for the font size.
*/
public float scaledDensity;