理解 Android 元视口缩放:我错过了什么?

发布于 2024-10-15 12:01:02 字数 3139 浏览 2 评论 0原文

我一直在尝试确定视口以及其中的内容如何受到用于使用 WebView 或本机浏览器绘制内容的视口元标记的影响。

我遇到的情况是一些明显的不一致。我创建了一个小页面(见下文),其中包含图像和一些用于显示视口大小的 JavaScript,这样我就可以直观地看到图像的缩放情况并获得准确的数字。

首先,一些观察结果:

  1. 没有一个视口宽度数字完全符合我的预期,只是接近。
  2. 当数字接近设备像素数时,绘图实际上是一对一完成的 - 或者至少看起来是这样。
  3. 如果页面尺寸(文档尺寸)小于视口尺寸,则视口编号会缩小。也就是说,视口并不总是代表最大可能的可见空间——仅代表当前的可见空间。
  4. 同样,在本机浏览器中,视口大小由顶部栏调整。当它滚出屏幕时,尺寸会增加。给出的数字用于全屏显示。

设备#1:物理屏幕为 1024x600,运行 Android 2.2。

  1. 初始规模=1.0 => 676x400
  2. 初始比例=1.0,宽度=设备宽度==> 676x400
  3. 初始比例=2,宽度=设备宽度==> 338x200
  4. 初始比例=2,宽度=设备宽度,目标密度dpi=设备dpi => 507x300
  5. 初始比例=0.5,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 800x473
  6. 初始比例=0.9,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 800x473
  7. 宽度=设备宽度,目标密度dpi=设备dpi => 1014x600
  8. 初始比例=1.0,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 1014x600
  9. 初始比例=0.5,宽度=设备宽度, 目标密度dpi=设备dpi,最小比例=0.1 => 2028x768
  10. 初始比例=0.5,宽度=设备宽度, 目标密度 dpi = 设备 dpi,最小比例 = 0.1,用户可扩展 = 否 => 1014x600

设备 #2:物理屏幕为 800x480,运行 Android 2.3.2。

  1. 初始规模=1.0 => 527x320
  2. 初始比例=1.0,宽度=设备宽度==> 527x320
  3. 初始比例=2,宽度=设备宽度==> 263x160
  4. 初始比例=2,宽度=设备宽度,目标密度dpi=设备dpi => 395x240
  5. 初始比例=0.5,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 790x480
  6. 初始比例=1.0,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 790x480
  7. 初始比例=0.5,宽度=设备宽度, 目标密度dpi =设备dpi,最小比例= 0.1 => 1580x768
  8. 初始比例=0.5,宽度=设备宽度, 目标密度dpi=设备dpi,最小比例=0.1,用户可扩展=否=> 790x480
  9. 宽度=1580,目标密度dpi=设备dpi==> 790x480
  10. 宽度=1580,目标密度dpi=设备dpi==> 790x480
  11. 宽度=1580,目标密度dpi=设备dpi,最小比例=0.1 =>790x480

在这些结果中,以下内容没有意义:

  1. 设备 #1,项目 5、6 和 10
  2. 设备 #2,项目 5、8、10、11、12

有谁知道那些不生产的设备发生了什么情况感觉?

有谁知道为什么许多值与物理像素的匹配度相差 10 个像素,但结果却好像它们匹配一样? (例如 1.7 和 2.6)

我是否做错了什么,或者似乎不可能缩小到超过 1.0,除非用户也被允许缩放并且设置了最小缩放值?

也就是说,即使有效值为 0.01 到 10,低于 1.0 的初始比例值也会被忽略,除非您还可以设置最小比例。

Android 文档确实说,当用户可缩放时,最小/最大缩放比例值被忽略。这似乎不太有用。而2.9-2.11似乎表明你不能只自己计算并设置宽度。

最后,我正在使用的 HTML:

<html>
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
<head>
    <meta name="viewport" content="initial-scale=0.5, width=device-width, target-densitydpi=device-dpi, minimum-scale=0.1, user-scalable=no" />
</head>
<body style="margin:0;">
<div id="bld" class="bld" style="position:absolute; width:250px; height:125px; left:50px; background-color:#ccccff;">Hello world.</div>
<img id="bl1" src="http://commondatastorage.googleapis.com/kf6nvr/images/1024x768.png" />
<script> 
$("#bl1").click(function(){
    var pageWidth = $(document).width();
    var pageHeight = $(document).height();
    var viewportWidth = $(window).width();
    var viewportHeight = $(window).height();

     $("#bld").html("Page width: "+pageWidth+"<br />pageHeight: "+pageHeight+"<br />port width: "+viewportWidth+"<br />port height: "+viewportHeight);
});
</script> 
</body>
</html>

那么...我缺少什么?

I have been trying to determine how the viewport -- and the contents within -- are affected by the viewport meta tag used for drawing content with WebView or with the native browser.

What I have run in to are some apparent inconsistencies. I created a small page (see below) with an image and some javascript for displaying the viewport size so I can visually see the scaling with the image as well as get the exact numbers.

First, a some observations:

  1. None of the viewport width numbers are exactly what I expected, just close.
  2. When the numbers are close to the device pixel count, the drawing is actually done one-for-one -- or at least is visibly looks that way.
  3. If the page size (document size) is under that of the viewport size, the viewport numbers shrink. That is, the viewport doesn't always necessarily represent the maximum possible visible space -- just the current visible space.
  4. Likewise, in the native browser, the viewport size is adjusted by the top bar. The size increases as it scrolls off the screen. The numbers given are for full screen display.

Device #1: Physical screen is 1024x600 and it's running Android 2.2.

  1. initial-scale=1.0 => 676x400
  2. initial-scale=1.0, width=device-width => 676x400
  3. initial-scale=2, width=device-width => 338x200
  4. initial-scale=2, width=device-width, target-densitydpi=device-dpi
    => 507x300
  5. initial-scale=0.5, width=device-width,
    target-densitydpi=device-dpi => 800x473
  6. initial-scale=0.9, width=device-width,
    target-densitydpi=device-dpi => 800x473
  7. width=device-width, target-densitydpi=device-dpi => 1014x600
  8. initial-scale=1.0, width=device-width,
    target-densitydpi=device-dpi => 1014x600
  9. initial-scale=0.5, width=device-width,
    target-densitydpi=device-dpi, minimum-scale=0.1 => 2028x768
  10. initial-scale=0.5, width=device-width,
    target-densitydpi=device-dpi, minimum-scale=0.1, user-scalable=no =>
    1014x600

Device #2: Physical screen is 800x480 and it's running Android 2.3.2.

  1. initial-scale=1.0 => 527x320
  2. initial-scale=1.0, width=device-width => 527x320
  3. initial-scale=2, width=device-width => 263x160
  4. initial-scale=2, width=device-width, target-densitydpi=device-dpi
    => 395x240
  5. initial-scale=0.5, width=device-width,
    target-densitydpi=device-dpi => 790x480
  6. initial-scale=1.0, width=device-width,
    target-densitydpi=device-dpi => 790x480
  7. initial-scale=0.5, width=device-width,
    target-densitydpi=device-dpi, minimum-scale=0.1 => 1580x768
  8. initial-scale=0.5, width=device-width,
    target-densitydpi=device-dpi, minimum-scale=0.1, user-scalable=no =>
    790x480
  9. width=1580, target-densitydpi=device-dpi => 790x480
  10. width=1580, target-densitydpi=device-dpi => 790x480
  11. width=1580, target-densitydpi=device-dpi, minimum-scale=0.1
    =>790x480

Of these results, the following don't make sense:

  1. Device #1, items 5, 6, and 10
  2. Device #2, items 5, 8, 10, 11, 12

Does anyone know what's going on with those that don't make sense?

Does anyone know why many of the values are 10 pixels shy of match the physical pixels, but that result is as if they match? (e.g. 1.7 and 2.6)

Am I doing something wrong, or does it appear that it's impossible to zoom out beyond 1.0 unless the user is also allowed to scale and the minimum-scale value is set?

That is, even though the valid values are 0.01 to 10, initial-scale values under 1.0 are ignored unless you can also set the minimum scale.

The Android docs do say when user-scalable is no that the min/max scale values are ignored. That doesn't seem very useful. And 2.9-2.11 seem to show that you can't just calculate it yourself and set the width.

Finally, the HTML I'm using:

<html>
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
<head>
    <meta name="viewport" content="initial-scale=0.5, width=device-width, target-densitydpi=device-dpi, minimum-scale=0.1, user-scalable=no" />
</head>
<body style="margin:0;">
<div id="bld" class="bld" style="position:absolute; width:250px; height:125px; left:50px; background-color:#ccccff;">Hello world.</div>
<img id="bl1" src="http://commondatastorage.googleapis.com/kf6nvr/images/1024x768.png" />
<script> 
$("#bl1").click(function(){
    var pageWidth = $(document).width();
    var pageHeight = $(document).height();
    var viewportWidth = $(window).width();
    var viewportHeight = $(window).height();

     $("#bld").html("Page width: "+pageWidth+"<br />pageHeight: "+pageHeight+"<br />port width: "+viewportWidth+"<br />port height: "+viewportHeight);
});
</script> 
</body>
</html>

So... what am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相对绾红妆 2024-10-22 12:01:02

你在那里打开了一些有趣的蠕虫。当您尝试更多的设备时,您可能会看到更多的奇怪现象和随机错误。有趣的时刻! :-)

我怀疑您可能想放弃,并尝试...

  • 坚持尽可能简单的设置。
  • 接受设备选择报告的像素宽度。
  • 依靠自适应/流体布局和相对宽度来使内容在不同的屏幕宽度上工作。
  • 使用本机 CSS 属性对圆角、阴影和渐变进行分辨率中性渲染。
  • 尽可能使用矢量格式(svg、图标字体等)
  • ,并且(重要)使用高分辨率边框图像以及背景-image 与受良好支持的 background-size 属性1 使事物渲染得漂亮且清晰2

1) 为了向旧版浏览器(如 MSIE8)提供向后兼容性,您需要使用双 background-image 声明 - 例如:

background-image: url(low-res.png);        /* CSS2 */
background-image: url(high-res.png), none; /* CSS3 */
background-size:  100px 10px;             /* CSS3 */

2) -webkit-max-device-pixel-ratio< /code>媒体查询也可能有帮助,但顾名思义,它仅适用于 webkit 浏览器。


Ramble:

新一代 Android 和 iOS 设备的屏幕 DPI 差异很大,因此它们不得不报告 CSS 像素 而不是实际的设备像素。这既是好事也是坏事——取决于你如何看待它。

这是,因为你不再能保证你习惯于使用过去几乎同质的屏幕进行精确到设备像素的控制。

另一方面,它是,因为您知道您的设计永远不会渲染得如此之小,以至于普通人无法阅读/使用。

使用 target-密度dpi=device-dpi 的问题在于,虽然它在 7 英寸宽 800px 屏幕上表现出色,但在 4 英寸宽 960px 屏幕上却会完全毁掉您的应用程序。

Interesting can of worms you've opened up there. As you try out more devices you'll probably see even more weirdness, and random bugs. Interesting times! :-)

I suspect that somewhere down the line you might want to give up, and just try to...

  • Stick with as simple settings as possible.
  • Accept the pixel width the device chooses to report.
  • Rely on adaptive/fluid layout and relative widths to make things work across different screen widths.
  • Use native CSS properties for a resolution neutral rendering of rounded corners, shadows and gradients.
  • Use vector formats (svg, icon-fonts, etc.) as much as possible
  • and (important) Use high-res border-images as well as background-images coupled with the well-supported background-size property1 to make things render nice and crisp2.

1) To provide backwards compatibility to older browsers (like MSIE8) you'll need to use double background-image declarations - like:

background-image: url(low-res.png);        /* CSS2 */
background-image: url(high-res.png), none; /* CSS3 */
background-size:  100px 10px;             /* CSS3 */

2) The -webkit-max-device-pixel-ratio media query may also help, but as the name implies it only works for webkit browsers.


Ramble:

The new generation Android and iOS devices have such varying screen DPIs that they've resorted to reporting CSS pixels rather than actual device pixels. This is both good or bad - depending on how you look at it.

It's bad because you're not guaranteed anymore the down-to-the-device-pixel control you were used to having, working with the mostly homogenous screens of yore.

On the other hand, it's good because you know your designs will never render so tiny that they can't be read/used by regular humans.

The problem with using target-densitydpi=device-dpi is that it while it works wonders on a 7inch wide 800px screen, it will completely ruin your application on a 4inch wide 960px screen.

牵你手 2024-10-22 12:01:02
$(document).ready(function() { 
$('meta[name=viewport]').attr('content','width=1024, user-scalable=no'); 
});

似乎适用于在应用正确的缩放后禁用用户缩放

$(document).ready(function() { 
$('meta[name=viewport]').attr('content','width=1024, user-scalable=no'); 
});

Seem to work for disabling the user scaling after the correct scaling have been applied

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文