当前位置: 首页 > 知识库问答 >
问题:

将屏幕密度放入正确的铲斗

商飞龙
2023-03-14

一组六个广义密度:

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

从每个手机显示的 wiki 页面

按比例缩小到桶中,即如果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

这是计算屏幕尺寸桶的正确方法吗?

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

values-hdpi/dimens
values-xhdpi/dimens
values-xxhdpi/dimens
values-xxxhdpi/dimens

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

<dimen name="network_quantity_margin_top">100dp</dimen>

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

共有3个答案

樊奇思
2023-03-14

从Android文档:

在某些情况下,您需要用dp表示尺寸,然后将其转换为像素。想象一个应用程序,在用户手指移动至少16像素后,滚动或投掷手势被识别。在基线屏幕上,用户必须移动16像素/160 dpi,相当于十分之一英寸(或2.5毫米)才能识别手势。在高密度显示器(240dpi)的设备上,用户必须移动16像素/240 dpi,相当于十五分之一英寸(或1.7毫米)。距离要短得多,因此应用程序对用户来说显得更敏感。

要解决此问题,手势阈值必须在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...

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

窦宏旷
2023-03-14

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

你基本上是正确的。

问题出在以下部分:

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

values-hdpi/dimens
values-xhdpi/dimens
values-xxhdpi/dimens
values-xxxhdpi/dimens

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

<dimen name="network_quantity_margin_top">100dp</dimen>

dp的目的被定义文件夹(如values hdpi/dimens)所挫败。密度像素在设计上与设备无关-在dpi=240的设备上,100dp的像素在dpi=480的设备上看起来同样宽/一样长。因此,如果你想让你的应用看起来一致,就不要为不同的屏幕密度提供不同的尺寸。

考虑这个问题的正确方法是认识到,受不同屏幕密度影响的唯一资源是可绘制的。dpi = 240 的屏幕上的可绘制对象看起来是密度 = 480 的屏幕的两倍。我相信您正在提供可绘制hdpi可绘制xhdpi文件夹来处理此问题。对于其他所有内容,尤其是尺寸,请使用 dp。对于文本大小,请使用缩放像素 - sp

更重要的是,您应该担心适用于Android的不同屏幕尺寸的范围。与5英寸手机相比,您将如何使用10英寸设备上的所有额外屏幕空间?诸如 -normal-大x大等限定词应该对您更感兴趣。

总结一下:

  • 考虑特定屏幕尺寸的所有设备都是相同的-当使用密度像素时,它们的屏幕密度无关紧要。
  • 对于您使用的每个可绘制资源,将它们的缩放版本放在您希望支持的存储桶中。请记住,如果您不为某个存储桶提供资源(例如可绘制-hdpi),android将从可绘制-xhdpi文件夹缩小您的可绘制文件(前提是定义了可绘制-xhdpi)。反之亦然:如果您将所有可绘制文件都放在可绘制-xhdpi中,android将在xxhdpi设备上放大您的可绘制文件。结果将是模糊的图形——因为放大。

我知道这有点陡峭。所以,如果你需要进一步澄清,请给我留言。

秦焱
2023-03-14

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

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

如果您使用px而不是dp(但没有),那么您必须自己对不同的屏幕进行缩放。

按比例缩小到桶中,即如果ppi为300,将进入hdpi桶,因为它小于320?

是的,但不是因为它小于320。如果有经验法则,我会说它是四舍五入到最接近的广义密度。请参阅以下插图,了解 Android 如何将实际密度大致映射到广义密度(图中并不准确):

留档的相关部分如下:

每个广义尺寸和密度跨越了实际屏幕尺寸和密度的范围。例如,两个都报告屏幕尺寸正常的设备在用手测量时,实际屏幕尺寸和长宽比可能略有不同。同样,两个报告屏幕密度为hdpi的设备的实际像素密度可能略有不同。Android将这些差异抽象到应用程序中,因此您可以提供针对通用尺寸和密度设计的UI,并让系统在必要时处理任何最终调整。

所以再一次,如果你只是在写一个应用程序,你不应该真正关心Android是如何做到这一点的。你应该关心的是:

    < li >在< code>dp中或使用< code > wrap _ content /< code > match _ parent 指定所有布局尺寸值,视情况而定(文本可以在< code>sp中,以额外匹配用户首选项,但除了文本之外不能有其他内容), < li >根据屏幕的物理尺寸和方向考虑不同的布局, < li >为不同的密度提供位图资源,只是为了避免模糊或像素化的伪像(因为如果您使用< code>dp或< code>wrap_content,Android会将其缩放到正确的物理大小)。

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

<罢工>请注意实际密度与广义密度。后者是<罢工>只有为开发人员提供了便利,因为不可能为每个屏幕都提供可绘图功能。这样,开发人员只需要提供3或4套图形,而Android会选择最合适的图形,并根据特定设备的需要进行进一步调整。(现在,可以使用一个矢量绘制,而不是使用许多预先缩放的光栅图形,这意味着质量更好、尺寸更小。)

这是计算屏幕尺寸桶的正确方法吗?

不,它不是。根据谷歌设备指标,你列出的所有设备都比你预期的高:

Galaxy S3    NA        NA
Nexus 4     318     xhdpi
Nexus 5X    424    xxhdpi
Nexus 5     445    xxhdpi
Nexus 6     493   xxxhdpi
Nexus 6P    515   xxxhdpi

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

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

你可以看到,除了一些明显的例外,选择最接近的广义密度的规则是成立的。

例外的是Nexus 6和6P,它们被列为< code>xxxhdpi,尽管LG G3具有更高的物理密度,仍然远远达不到640px/in。Android One是< code>hdpi,但它的密度仅略高于Nexus 7 '12的< code>tvdpi。Chromebox 30和Chromebook Pixel(诚然,不是Android)被分配给bucket < code > mdpi 和< code>xhdpi,即使它们在物理上分别低于< code>ldpi和< code>hdpi。

 类似资料:
  • 对于每个android可绘制屏幕密度(hdpi、ldpi、xhdpi等),建议采用什么方法缩放图像?我们应该使用源图像分辨率作为最高密度(xxhdpi)的分辨率,并从那里开始缩放吗?在我的例子中,我明确地将布局中的图像大小设置为50 x 50 dp,那么我是否应该缩放可绘制图像,使我的mdpi为50x50,并以此为基础确定其他分辨率? 附言:为什么我们必须手动缩放绘图,如果它们在放置时无论如何都会

  • 我不明白以下几点: 三星Galaxy S3显示720px 1280px,屏幕尺寸为4.8英寸 因此,屏幕密度可以评估为305dpi 在Android屏幕支持推荐页面中,305dpi对应于“xhdpi”限定符 所以我的问题是:为什么运行在GS3上的应用程序会从“mdpi”限定符中获取资源? 作为更新,请参阅我的代码以测试它: main.xml: strings.xml文件夹{"值","值-ldpi"

  • 我如何才能使它的应用程序是优化的所有屏幕?

  • null 这是这个问题的视频 下面是我如何切换屏幕的代码: 从游戏第一次打开到主菜单: GamesCreen:

  • 本文向大家介绍Android屏幕锁屏弹窗的正确姿势DEMO详解,包括了Android屏幕锁屏弹窗的正确姿势DEMO详解的使用技巧和注意事项,需要的朋友参考一下 在上篇文章给大家介绍了Android程序开发仿新版QQ锁屏下弹窗功能。今天通过本文给大家分享android锁屏弹窗的正确姿势。 最近在做一个关于屏幕锁屏悬浮窗的功能,于是在网上搜索了很多安卓屏幕锁屏的相关资料,鉴于网上的资料比较零碎,所以我

  • 问题内容: 我听说将block元素放入内联元素是HTML的罪过: 但是,如果您像样式表那样设置外部锚点,该怎么办?还是错吗?关于块级和内联元素的HTML 4.01规范似乎是这样认为的: 样式表提供了一种方法来指定任意元素的呈现,包括将元素呈现为块还是内联。在某些情况下,例如列表元素的内联样式,这可能是适当的,但总的来说,不鼓励作者以这种方式覆盖HTML元素的常规解释。 有人对此问题有其他建议吗?