【问题标题】:Android multiple screen sizes with same densityAndroid多个屏幕尺寸具有相同的密度
【发布时间】:2010-04-14 14:30:47
【问题描述】:

我对密度感到困惑。我看到在中等密度下,屏幕分辨率可以是 320x480、480x800 或 480x854。因此,如果我在 mdpi 文件夹中有一个 300 像素宽的图像,它如何在所有 3 种不同的屏幕尺寸(主要是 320x480 与其他 2 种)上看起来都一样? 通过看起来相同的尺寸,我的意思是根据屏幕尺寸放大或缩小。谢谢。

【问题讨论】:

标签: android


【解决方案1】:

这里需要理解三个不同但相互关联的概念:屏幕密度(每英寸/厘米的像素数,或通常称为打印机中每英寸点数的 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,它会保持原样,只是看起来更小。

那里!给你一个很长的答案。我希望这是有道理的。

【讨论】:

  • 如何区分 480X800 和 480X854 屏幕。我们可以选择将一个图像放在 hdpi 文件夹中。在我的情况下,480X800 图像不支持 480X854 图像。有什么想法吗?
  • @Praveen Chandrasekaran:据我所知,您无法根据 hdpi 文件夹区分两者,但这很正常。两个屏幕可能具有相同的密度。但是,您可以通过编程方式获取屏幕尺寸。请参阅 Display Metrics 类 (developer.android.com/reference/android/util/…) 这是一种更可靠的方法 - 屏幕的密度与其像素数无关。例如,没有绝对的理由说明屏幕不能具有高密度并且只有 480x320 像素。
  • “一个 300 像素宽的图像将是 1.875 英寸宽。这是通过像素大小 (300) / 密度 (240) 计算得出的”,根据前面的句子,240 应该是 160
  • 那么我怎么知道每个文件夹的大小?
  • 所以,我需要为具有不同屏幕尺寸的相同密度(在我的情况下是 xhdpi)设备相应地设置边距(或任何属性)。我必须以编程方式检查屏幕尺寸,而不是应用边距。我对吗?感谢有用的评论@SteveHaley
【解决方案2】:

为了完整性,还要检查这些控制布局的选项:

目录限定符:

尺寸:小号、普通号、大号 密度: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

【讨论】:

    【解决方案3】:

    如果我有一个 300 像素宽的图片 在 mdpi 文件夹中,它将如何 所有 3 种不同的尺码看起来都一样 屏幕尺寸(主要是 320x480 与 其他 2)?

    图像的物理外观取决于屏幕密度,而不是屏幕尺寸。您的-mdpi 文件夹与屏幕大小无关——它与屏幕密度有关。

    【讨论】:

      【解决方案4】:

      这就是设备独立像素 (DIP) 的用途。而不是320px320dip

      http://developer.android.com/guide/practices/screens_support.html

      【讨论】:

        【解决方案5】:

        能否确认一下屏幕密度的计算公式?

        正如我所读,以下是公式:

        密度 = 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)是相同的。

        您能确认一下吗?

        谢谢, 拉姆

        【讨论】:

          【解决方案6】:

          实际上计算设备物理屏幕大小的代码如下:

          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);
          

          【讨论】:

            猜你喜欢
            • 2023-04-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多