将屏幕密度放入正确的桶中

ant*_*009 33 android

一组六个广义密度:

ldpi (low) ~120dpi
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi (extra-extra-high) ~480dpi
xxxhdpi (extra-extra-extra-high) ~640dpi
Run Code Online (Sandbox Code Playgroud)

从每个手机显示的维基页面

缩小到桶中,即如果ppi是300,那么它会进入hdpi桶,因为它少于320?

Galaxy S3 306ppi -> bucket hdpi
Nexus 4  318ppi -> bucket hdpi
Nexus 5  445ppi -> bucket xhdpi
Nexus 5X 432ppi -> bucket xhdpi
Nexus 6  493ppi -> bucket xxhdpi 
Nexus 6P 518ppi -> bucket xxhdpi
Run Code Online (Sandbox Code Playgroud)

这是解决屏幕大小的桶的正确方法吗?

我问的原因是因为我创建了以下值目录资源:

values-hdpi/dimens
values-xhdpi/dimens
values-xxhdpi/dimens
values-xxxhdpi/dimens
Run Code Online (Sandbox Code Playgroud)

dimens.xml我有不同的边距,并根据桶大小设置dp即

<dimen name="network_quantity_margin_top">100dp</dimen>
Run Code Online (Sandbox Code Playgroud)

我很想知道这是否是正确的方法.

are*_*lek 42

我问的原因是因为我创建了以下值目录资源.(...)在dimens.xml中,我有不同的边距,并根据桶大小设置dp.(...)我很想知道这是否是正确的方法.

我不确定为什么你想要dp根据密度指定不同的边距.dp对于基线密度,将边距指定为一次,已经为您处理了所有其他密度,这意味着在任何设备上显示时,边距的物理尺寸将是相同的.

如果你使用px而不是dp(但不是),那么你必须自己进行不同屏幕的缩放.

缩小到桶中,即如果ppi是300,那么它会进入hdpi桶,因为它少于320?

是的,但不是因为它小于320.如果有一个经验法则我会说它是四舍五入到最近的广义密度.请参阅此插图,了解Android如何将实际密度粗略地映射到广义密度(图不准确):

广义密度

文档的相关部分是这样的:

每个通用尺寸和密度涵盖一系列实际屏幕尺寸和密度.例如,两个都报告屏幕尺寸正常的设备可能具有实际的屏幕尺寸和纵横比,当手动测量时,它们略有不同.类似地,报告屏幕密度为hdpi的两个设备可能具有略微不同的实际像素密度.Android将这些差异抽象为应用程序,因此您可以提供针对通用大小和密度设计的UI,并让系统根据需要处理任何最终调整.

再说一次,如果您只是编写应用程序,那么您应该不关心Android 如何做到这一点.你应该关心的是:

  • 指定所有布局尺寸在值dpwrap_content/ match_parent酌情(文本可以是sp额外地匹配所述用户偏好,但没有任何非文本),
  • 根据屏幕的物理尺寸方向考虑不同的布局,
  • 提供不同密度的位图资源,只是为了避免模糊或像素化的伪像(因为如果你使用dp或者Android会将它们缩放到具有正确的物理尺寸wrap_content).

Android将查找最佳匹配资源,然后dp根据所使用屏幕实际密度,根据需要透明地处理单元的任何缩放.dp单位到屏幕像素的转换很简单:px = dp * (dpi / 160).

注意实际密度而不是广义密度.后者只是开发人员的便利,因为不可能为每个屏幕提供可绘制的内容.这样开发人员只需要提供3或4组图形,而Android会选择最接近的版本,并根据特定设备的需要进一步调整.(现在可以使用一个矢量可绘制而不是许多预先缩放的光栅图形,这意味着更好的质量和更小的尺寸.)

这是解决屏幕大小的桶的正确方法吗?

不它不是.根据Google设备指标,您列出的所有设备都会超出您的预期:

Galaxy S3    NA        NA
Nexus 4     318     xhdpi
Nexus 5X    424    xxhdpi
Nexus 5     445    xxhdpi
Nexus 6     493   xxxhdpi
Nexus 6P    515   xxxhdpi
Run Code Online (Sandbox Code Playgroud)

我从该列表中获取了一些其他设备,并根据实际物理密度绘制了不同设备如何落入密度桶.

一些Android设备的密度桶

Chromebox 30            101      mdpi
Chromebook 11           135      mdpi
Samsung Galaxy Tab 10   149      mdpi
Nexus 7 '12             216     tvdpi
Android One             218      hdpi
Chromebook Pixel        239     xhdpi
Nexus 9                 288     xhdpi
Nexus 10                299     xhdpi
Moto X                  312     xhdpi
Nexus 4                 318     xhdpi
Nexus 7 '13             323     xhdpi 
Moto G                  326     xhdpi
Dell Venue 8            359     xhdpi
LG G2                   424    xxhdpi
Nexus 5X                424    xxhdpi
HTC One M8              441    xxhdpi
Nexus 5                 445    xxhdpi
Nexus 6                 493   xxxhdpi
Nexus 6P                515   xxxhdpi
LG G3                   534    xxhdpi
Run Code Online (Sandbox Code Playgroud)

您可以看到,除了一些值得注意的例外情况,选择最接近的广义密度的规则成立.

例外的是Nexus 6和6P,xxxhdpi即使LG G3具有更高的物理密度并且仍然远远不是640px/in ,因此被列为.Android One虽然hdpi比Nexus 7 '12稍微密集一些tvdpi.Chromebox 30和Chromebook Pixel(不可否认,不是Android)被分配到存储桶mdpi,xhdpi即使它们分别低于ldpi和低于hdpi.


Vik*_*ram 10

我很想知道这是否是正确的方法.

大多是正确的.

问题出在这一部分:


我问的原因是因为我创建了以下值目录资源:

values-hdpi/dimens
values-xhdpi/dimens
values-xxhdpi/dimens
values-xxxhdpi/dimens
Run Code Online (Sandbox Code Playgroud)

在dimens.xml中,我有不同的边距,并根据桶大小设置dp即

<dimen name="network_quantity_margin_top">100dp</dimen>
Run Code Online (Sandbox Code Playgroud)

dp通过定义文件夹来获得失败的目的values-hdpi/dimens.密度像素,根据设计,与设备无关 - 在dpi = 240的设备上100dpdpi = 480的设备上看起来同样宽/长.因此,如果您希望自己的应用看起来一致,请不要为不同的屏幕密度提供不同的尺寸.

考虑这一点的正确方法是认识到受不同屏幕密度影响的唯一资源是drawable.一个drawable与DPI = 240看起来在屏幕上的两倍大相比,具有密度= 480的屏幕我相信你提供的文件夹一样drawable-hdpi,drawable-xhdpi等来处理这个问题.对于其他一切,尤其是尺寸,请使用dp.对于文字大小,请使用scaled-pixels - sp.

更重要的是,您应该担心可用于Android的不同屏幕尺寸的范围.与5英寸手机相比,你如何使用10英寸设备上的所有额外屏幕空间?预选赛如-normal,-large,xlarge应该更感兴趣的是你的.

总结一下:

  • 考虑到某个屏幕尺寸相同的所有设备 - 使用时它们的屏幕密度无关紧要density pixels.
  • 对于drawable您使用的每个资源,将其缩放版本放在您希望支持的存储区中.请记住,如果你没有为某个存储桶提供资源(比方说drawable-hdpi),android会缩小你的drawables drawable-xhdpi文件夹(如果定义了drawable-xhdpi).反过来也是如此:如果你已经放置了所有的drawables drawable-xhdpi,android会扩展你的drawables在xxhdpi设备上.结果将是模糊的图形 - 因为扩大规模.

我知道这里有一点陡峭的坡度:).所以,如果你需要澄清一些,请给我留言.


Jst*_*wll 6

从Android文档:

支持多个屏幕

在某些情况下,您需要在dp中表示尺寸,然后将它们转换为像素.想象一下这样一种应用,其中在用户的手指移动了至少16个像素之后识别出滚动或拖动手势.在基线屏幕上,用户必须移动16像素/ 160 dpi,等于识别手势之前的1/10英寸(或2.5 mm).在具有高密度显示器(240dpi)的设备上,用户必须移动16像素/ 240 dpi,等于1/15英寸(或1.7 mm).距离更短,因此应用对用户更敏感.

要解决此问题,手势阈值必须以dp中的代码表示,然后转换为实际像素.例如:

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...
Run Code Online (Sandbox Code Playgroud)

DisplayMetrics.density字段指定必须使用dp单位转换为像素,根据当前屏幕密度的比例因子.在中密度屏幕上,DisplayMetrics.density等于1.0; 在高密度屏幕上,它等于1.5; 在超高密度屏幕上,它等于2.0; 在低密度屏幕上,它等于0.75.此数字是您应该按顺序乘以dp单位以获得当前屏幕的实际像素数的因子.(然后添加0.5f以将图形舍入到最接近的整数,转换为整数时.)有关更多信息,请参阅 DisplayMetrics类.