理解 Android 元视口缩放:我错过了什么?
我一直在尝试确定视口以及其中的内容如何受到用于使用 WebView 或本机浏览器绘制内容的视口元标记的影响。
我遇到的情况是一些明显的不一致。我创建了一个小页面(见下文),其中包含图像和一些用于显示视口大小的 JavaScript,这样我就可以直观地看到图像的缩放情况并获得准确的数字。
首先,一些观察结果:
- 没有一个视口宽度数字完全符合我的预期,只是接近。
- 当数字接近设备像素数时,绘图实际上是一对一完成的 - 或者至少看起来是这样。
- 如果页面尺寸(文档尺寸)小于视口尺寸,则视口编号会缩小。也就是说,视口并不总是代表最大可能的可见空间——仅代表当前的可见空间。
- 同样,在本机浏览器中,视口大小由顶部栏调整。当它滚出屏幕时,尺寸会增加。给出的数字用于全屏显示。
设备#1:物理屏幕为 1024x600,运行 Android 2.2。
- 初始规模=1.0 => 676x400
- 初始比例=1.0,宽度=设备宽度==> 676x400
- 初始比例=2,宽度=设备宽度==> 338x200
- 初始比例=2,宽度=设备宽度,目标密度dpi=设备dpi => 507x300
- 初始比例=0.5,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 800x473
- 初始比例=0.9,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 800x473
- 宽度=设备宽度,目标密度dpi=设备dpi => 1014x600
- 初始比例=1.0,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 1014x600
- 初始比例=0.5,宽度=设备宽度, 目标密度dpi=设备dpi,最小比例=0.1 => 2028x768
- 初始比例=0.5,宽度=设备宽度, 目标密度 dpi = 设备 dpi,最小比例 = 0.1,用户可扩展 = 否 => 1014x600
设备 #2:物理屏幕为 800x480,运行 Android 2.3.2。
- 初始规模=1.0 => 527x320
- 初始比例=1.0,宽度=设备宽度==> 527x320
- 初始比例=2,宽度=设备宽度==> 263x160
- 初始比例=2,宽度=设备宽度,目标密度dpi=设备dpi => 395x240
- 初始比例=0.5,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 790x480
- 初始比例=1.0,宽度=设备宽度, 目标密度 dpi = 设备 dpi => 790x480
- 初始比例=0.5,宽度=设备宽度, 目标密度dpi =设备dpi,最小比例= 0.1 => 1580x768
- 初始比例=0.5,宽度=设备宽度, 目标密度dpi=设备dpi,最小比例=0.1,用户可扩展=否=> 790x480
- 宽度=1580,目标密度dpi=设备dpi==> 790x480
- 宽度=1580,目标密度dpi=设备dpi==> 790x480
- 宽度=1580,目标密度dpi=设备dpi,最小比例=0.1 =>790x480
在这些结果中,以下内容没有意义:
- 设备 #1,项目 5、6 和 10
- 设备 #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:
- None of the viewport width numbers are exactly what I expected, just close.
- 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.
- 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.
- 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.
- initial-scale=1.0 => 676x400
- initial-scale=1.0, width=device-width => 676x400
- initial-scale=2, width=device-width => 338x200
- initial-scale=2, width=device-width, target-densitydpi=device-dpi
=> 507x300 - initial-scale=0.5, width=device-width,
target-densitydpi=device-dpi => 800x473 - initial-scale=0.9, width=device-width,
target-densitydpi=device-dpi => 800x473 - width=device-width, target-densitydpi=device-dpi => 1014x600
- initial-scale=1.0, width=device-width,
target-densitydpi=device-dpi => 1014x600 - initial-scale=0.5, width=device-width,
target-densitydpi=device-dpi, minimum-scale=0.1 => 2028x768 - 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.
- initial-scale=1.0 => 527x320
- initial-scale=1.0, width=device-width => 527x320
- initial-scale=2, width=device-width => 263x160
- initial-scale=2, width=device-width, target-densitydpi=device-dpi
=> 395x240 - initial-scale=0.5, width=device-width,
target-densitydpi=device-dpi => 790x480 - initial-scale=1.0, width=device-width,
target-densitydpi=device-dpi => 790x480 - initial-scale=0.5, width=device-width,
target-densitydpi=device-dpi, minimum-scale=0.1 => 1580x768 - initial-scale=0.5, width=device-width,
target-densitydpi=device-dpi, minimum-scale=0.1, user-scalable=no =>
790x480 - width=1580, target-densitydpi=device-dpi => 790x480
- width=1580, target-densitydpi=device-dpi => 790x480
- width=1580, target-densitydpi=device-dpi, minimum-scale=0.1
=>790x480
Of these results, the following don't make sense:
- Device #1, items 5, 6, and 10
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你在那里打开了一些有趣的蠕虫。当您尝试更多的设备时,您可能会看到更多的奇怪现象和随机错误。有趣的时刻! :-)
我怀疑您可能想放弃,并尝试...
边框图像
以及背景-image
与受良好支持的background-size
属性1 使事物渲染得漂亮且清晰2。1) 为了向旧版浏览器(如 MSIE8)提供向后兼容性,您需要使用双
background-image
声明 - 例如: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...
border-image
s as well asbackground-image
s coupled with the well-supportedbackground-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: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.似乎适用于在应用正确的缩放后禁用用户缩放
Seem to work for disabling the user scaling after the correct scaling have been applied