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

Posted

技术标签:

【中文标题】理解 Android 元视口缩放:我错过了啥?【英文标题】:Making Sense of Android meta-viewport scaling: What am I missing?理解 Android 元视口缩放:我错过了什么? 【发布时间】:2011-06-21 01:15:37 【问题描述】:

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

我遇到的是一些明显的不一致。我创建了一个带有图像和一些用于显示视口大小的 javascript 的小页面(见下文),这样我就可以直观地看到图像的缩放比例以及获得确切的数字。

首先,一些观察:

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

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

    初始比例=1.0 => 676x400 initial-scale=1.0, width=device-width => 676x400 initial-scale=2, width=device-width => 338x200 初始比例=2,宽度=设备宽度,目标密度dpi=设备-dpi => 507x300 初始比例=0.5,宽度=设备宽度, 目标密度dpi=设备dpi => 800x473 初始比例=0.9,宽度=设备宽度, 目标密度dpi=设备dpi => 800x473 width=device-width, target-densitydpi=device-dpi => 1014x600 初始比例=1.0,宽度=设备宽度, 目标密度dpi=设备dpi => 1014x600 初始比例=0.5,宽度=设备宽度, target-densitydpi=device-dpi, minimum-scale=0.1 => 2028x768 初始比例=0.5,宽度=设备宽度, 目标密度dpi=设备-dpi,最小比例=0.1,用户可缩放=否=> 1014x600

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

    初始比例=1.0 => 527x320 initial-scale=1.0, width=device-width => 527x320 initial-scale=2, width=device-width => 263x160 初始比例=2,宽度=设备宽度,目标密度dpi=设备-dpi => 395x240 初始比例=0.5,宽度=设备宽度, 目标密度dpi=设备dpi => 790x480 初始比例=1.0,宽度=设备宽度, 目标密度dpi=设备dpi => 790x480 初始比例=0.5,宽度=设备宽度, target-densitydpi=device-dpi, minimum-scale=0.1 => 1580x768 初始比例=0.5,宽度=设备宽度, 目标密度dpi=设备-dpi,最小比例=0.1,用户可缩放=否=> 790x480 width=1580, target-densitydpi=device-dpi => 790x480 width=1580, target-densitydpi=device-dpi => 790x480 宽度=1580,目标密度dpi=设备dpi,最小比例=0.1 =>790x480

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

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

有谁知道那些没有意义的事情是怎么回事?

有谁知道为什么许多值比物理像素低 10 像素,但结果却好像它们匹配? (例如 1.7 和 2.6)

我是不是做错了什么,或者除非用户也被允许缩放并且设置了 minimum-scale 值,否则似乎不可能缩小到 1.0 以上?

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

Android docs do 表示当 user-scalable 为 no 时,最小/最大比例值将被忽略。这似乎不是很有用。而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>

那么...我错过了什么?

【问题讨论】:

我现在已将此部分作为缺陷提交:goo.gl/rNvGE 你在那里打开的有趣的蠕虫罐头。我建议您尽量坚持使用最简单的设置,并尽可能依赖流畅的布局和相对宽度。祝你好运! 没错,但是如果您无意中添加了一个视口设置,导致您的视口在 640 像素的屏幕上认为它只有 320 像素宽,尽管尽了最大努力做“正确的事情”,您的内容无论您的流畅布局和相对宽度有多好,都会看起来很糟糕。您会注意到,在前两个设置中,视口 与屏幕匹配并导致发生像素缩放并不需要太多时间。因此,拥有不会触发其中一种奇怪行为的良好设置非常重要。 到目前为止,视口仍然是一项疯狂的业务。是的,我也在看着你,媒体查询。 顺便说一句,在我看来,宽度上的 10px 是占右侧滚动条的原因! 【参考方案1】:

你在那里打开的有趣的蠕虫罐头。当您尝试更多设备时,您可能会看到更多怪异和随机错误。有趣的时代! :-)

我怀疑你可能想放弃,然后尝试...

坚持尽可能简单的设置。 接受设备选择报告的像素宽度。 依靠自适应/流畅的布局和相对宽度来使事情在不同的屏幕宽度上工作。 使用原生 CSS 属性实现圆角、阴影和渐变的分辨率中性渲染。 尽可能使用矢量格式(svg、图标字体等) 和(重要)使用高分辨率的border-images 和background-images 加上得到良好支持的background-size property1 来渲染又好又脆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 媒体查询可能也有帮助,但顾名思义,它只适用于 webkit 浏览器。


漫步:

新一代 Android 和 ios 设备具有如此不同的屏幕 DPI,以至于他们求助于报告 CSS pixels 而不是实际的设备像素。这是好是坏 - 取决于你如何看待它。

不好,因为不再保证您已经习惯了在大多数同质屏幕上工作的设备像素控制。

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

使用target-densitydpi=device-dpi 的问题在于,虽然它在 7 英寸宽 800 像素的屏幕上效果很好,但它会完全破坏您在 4 英寸宽 960 像素屏幕上的应用程序。

【讨论】:

【参考方案2】:
$(document).ready(function()  
$('meta[name=viewport]').attr('content','width=1024, user-scalable=no'); 
);

在应用正确缩放后似乎可以禁用用户缩放

【讨论】:

以上是关于理解 Android 元视口缩放:我错过了啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android Webview 中使用元视口宽度

所有移动浏览器的完整网页和禁用缩放视口元标记

检测移动缩放和默认移动分辨率

iOS 捏缩放 - 现在无法通过视口禁用

事件溯源和 CQRS,我错过了啥?

使用视口元标记实现最小宽度