【发布时间】:2010-04-14 14:30:47
【问题描述】:
我对密度感到困惑。我看到在中等密度下,屏幕分辨率可以是 320x480、480x800 或 480x854。因此,如果我在 mdpi 文件夹中有一个 300 像素宽的图像,它如何在所有 3 种不同的屏幕尺寸(主要是 320x480 与其他 2 种)上看起来都一样? 通过看起来相同的尺寸,我的意思是根据屏幕尺寸放大或缩小。谢谢。
【问题讨论】:
标签: android
我对密度感到困惑。我看到在中等密度下,屏幕分辨率可以是 320x480、480x800 或 480x854。因此,如果我在 mdpi 文件夹中有一个 300 像素宽的图像,它如何在所有 3 种不同的屏幕尺寸(主要是 320x480 与其他 2 种)上看起来都一样? 通过看起来相同的尺寸,我的意思是根据屏幕尺寸放大或缩小。谢谢。
【问题讨论】:
标签: android
这里需要理解三个不同但相互关联的概念:屏幕密度(每英寸/厘米的像素数,或通常称为打印机中每英寸点数的 DPI)、物理屏幕尺寸(以英寸或厘米为单位)和像素数 (也称为分辨率,以像素为单位)。
这些术语不可互换,您需要了解它们如何相互关联,以免与问题混淆。通常,您可以忽略物理屏幕尺寸,因为这已经计入了密度。例如,3 英寸宽和 300 像素宽的屏幕将具有 100 的 DPI。此外,手机屏幕往往具有大致相同的物理尺寸,即使像素数量非常不同。
因此,让我们考虑分辨率为 480x320 且密度约为 160dpi 的 G1 或 Hero 的屏幕。一个 300 像素宽的图像将是 1.875 英寸宽。这是通过像素大小 (300) / 密度 (160) 计算的。现在,如果将其与 Nexus One、Droid 或类似设备的屏幕进行比较,这些型号的屏幕分辨率更高,约为 800x480,高密度约为 240dpi。如果您显示相同的 300 像素宽的图像,它现在只会以大约一又四分之一英寸的宽度显示。换句话说,它会小得多。这可能是个问题,因为如果图像包含文本,则文本可能不再可读。
可以告诉 Android 自动缩放图像以适应这些不同的屏幕,使其看起来仍然是相同的大小。这是通过在与密度无关的像素中设置大小来完成的。如果某物是 100dp 宽,那么它在中等密度屏幕上将是 100px 宽。在高密度屏幕上,它将是 150 像素宽,但它们在实际屏幕上看起来都差不多。但是,如果这样做,您的图像可能会有点模糊。就像在图片查看程序中将照片放大得太近一样;边缘会变得模糊,因为它会在您缩放时“拉伸”它们。
解决这个问题的方法是使用 mdpi、hdpi 等文件夹。你给 Android 一个已经缩放的图像,所以它不必自己做。显然,如果您只是在 Photoshop 中自己拉伸图像,那么它看起来不会更好。但通常会调整非常大的图像的大小以使其适合移动屏幕。在这种情况下,您只需将它们的大小调整 3 次,每次调整为不同的分辨率。
所以最后回答您的具体问题:如果您将图像放在 mdpi 文件夹中,则无论屏幕分辨率如何,只要它们的密度相同,它的大小都会完全相同。将改变的是它们周围有多少空间,例如一个 320x320px 宽的图像将填满 320x480 屏幕的大部分,但仅占 480x800 屏幕的大约三分之一。但是,如上所述,通常更高分辨率的手机也有更密集的屏幕。在这种情况下,Android 不会在您的 mdpi 文件夹中查找图像 - 它会转到 hdpi 文件夹,如果在那里找不到它,它将采用默认的“drawable”文件夹。然后,如果您使用过 DP,它会自动缩放,或者如果您使用过 PX,它会保持原样,只是看起来更小。
那里!给你一个很长的答案。我希望这是有道理的。
【讨论】:
为了完整性,还要检查这些控制布局的选项:
目录限定符:
尺寸:小号、普通号、大号 密度:ldpi、mdpi、hdpi、nodpi(无自动缩放) 长宽比:长,不长 方向:陆地 用法:res/layout/my_layout.xml
res/layout-small/my_layout.xml
res/layout-large/my_layout.xml
res/layout-large-long/my_layout.xml
res/layout-large-land/my_layout.xml
res/drawable-ldpi/my_icon.png
res/drawable-mdpi/dpi/my_icon.png
res/drawable-hdpi/my_icon.png
res/drawable-nodpi/composite.xml
将您的应用限制为特定的屏幕尺寸(通过 AndroidManifest):
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true" />
...
</manifest>
对于代码级 tweeking:
float scale = getContext().getResources().getDisplayMetrics().density;
别忘了:
dpi = 160; //At 160dpi
pixels = dips * (density / dpi)
这一切都在这个文档中: developer.android.com:Supporting Multiple Screens
【讨论】:
如果我有一个 300 像素宽的图片 在 mdpi 文件夹中,它将如何 所有 3 种不同的尺码看起来都一样 屏幕尺寸(主要是 320x480 与 其他 2)?
图像的物理外观取决于屏幕密度,而不是屏幕尺寸。您的-mdpi 文件夹与屏幕大小无关——它与屏幕密度有关。
【讨论】:
这就是设备独立像素 (DIP) 的用途。而不是320px 写320dip。
http://developer.android.com/guide/practices/screens_support.html
【讨论】:
能否确认一下屏幕密度的计算公式?
正如我所读,以下是公式:
密度 = SQRT (wp^2 + hp^2)/屏幕尺寸
wp -> 屏幕宽度(以 px 为单位) hp -> 屏幕高度(以 px 为单位) 屏幕尺寸 -> 物理屏幕尺寸(对角线英寸)
屏幕尺寸 (320x480) = SQRT(102400 + 230400) /160 = 3.6 英寸
屏幕尺寸 (480x800) = SQRT(640000 + 230400) /160 = 5.8 英寸
屏幕尺寸 (480x854) = SQRT(729316 + 230400) /160 = 6.12 英寸
因此,布局(UI 屏幕)由屏幕尺寸驱动(小:5") 和可绘制资源(图像)由屏幕密度驱动。
而且,如果屏幕的密度不同,图像的大小(以像素为单位)不会改变 (320x480、480x800 或 480x854)是相同的。
您能确认一下吗?
谢谢, 拉姆
【讨论】:
实际上计算设备物理屏幕大小的代码如下:
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
double x = Math.pow(dm.widthPixels/dm.xdpi,2);
double y = Math.pow(dm.heightPixels/dm.ydpi,2);
double screenInches = Math.sqrt(x+y);
【讨论】: