Android 设备(手机、平板电脑、电视等)不仅有不同的屏幕尺寸,而且其屏幕也有不同的像素尺寸。也就是说,有可能一部设备的屏幕为每平方英寸 160 像素,而另一部设备的屏幕在相同的空间内可以容纳 480 像素。如果您不考虑像素密度的这些差异,系统可能会缩放图片(导致图片变模糊),或者图片可能会以完全错误的尺寸显示。
您必须避免的第一个陷阱是使用像素来定义距离或尺寸。使用像素来定义尺寸会带来问题,因为不同的屏幕具有不同的像素密度,所以同样数量的像素在不同的设备上可能对应于不同的物理尺寸。
要在密度不同的屏幕上保留界面的可见尺寸,您必须使用密度无关像素 (dp) 作为度量单位来设计界面。dp 是一个虚拟像素单位,1 dp 约等于中密度屏幕(160dpi;“基准”密度)上的 1 像素。对于其他每个密度,Android 会将此值转换为相应的实际像素数。
例如,考虑图 1 中的两部设备。如果将某个视图定义为“100px”宽,那么它在左侧设备上看起来要大得多。因此,您必须改用“100dp”来确保它在两个屏幕上看起来大小相同。
不过,在定义文本大小时,您应改用可缩放像素 (sp) 作为单位(但切勿将 sp 用于布局尺寸)。默认情况下,sp 单位与 dp 大小相同,但它会根据用户的首选文本大小来调整大小。
例如,当您指定两个视图的间距时,请使用 dp
:
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/clickme" android:layout_marginTop="20dp" />
当指定文本大小时,请一律使用 sp
:
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" />
在某些情况下,您需要以 dp
表示尺寸,然后将其转换为像素。dp 单位转换为屏幕像素很简单:
px = dp * (dpi / 160)
假设在某一应用中,用户的手指至少移动 16 像素之后,系统会识别出滚动或滑动手势,那么在基准屏幕上,用户的手指必须至少移动 16 pixels / 160 dpi
,相当于 1 英寸的 1/10(2.5 毫米),相应手势才能被识别;而在配备高密度显示屏 (240dpi) 的设备上,用户的手指必须至少移动 16 pixels / 240 dpi
,相当于 1 英寸的 1/15(1.7 毫米)。此距离短得多,因此用户会感觉应用在该设备上更灵敏。
要解决此问题,手势阈值必须在代码中以 dp
表示,然后再转换为实际像素。例如:
1 // The gesture threshold expressed in dp 2 private static final float GESTURE_THRESHOLD_DP = 16.0f; 3 4 // Get the screen‘s density scale 5 final float scale = getResources().getDisplayMetrics().density; 6 // Convert the dps to pixels, based on density scale 7 mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f); 8 9 // Use mGestureThreshold as a distance in pixels... 10
DisplayMetrics.density
字段根据当前像素密度指定要将 dp
单位转换为像素而必须使用的缩放系数。对于中密度屏幕,DisplayMetrics.density
等于 1.0;对于高密度屏幕,它等于 1.5;对于超高密度屏幕,它等于 2.0;对于低密度屏幕,它等于 0.75。此数字是一个系数,用其乘以 dp
单位,即可得出当前屏幕的实际像素数。
原文:https://www.cnblogs.com/5igis/p/5igis_12609.html