我正在开发平板电脑7英寸Kindle Fire HD和Nexus 7的应用程序。 这两个应用程序具有相同的大小和相同的屏幕分辨率。但是,我运行我的应用程序,它是非常不同的。为什么呢?
这似乎是因为nexus 7被检测为TVDPI,而Kindle Fire HD是HDPI。 如何基于1280 * 800型号进行相同的渲染?
谢谢
答案 0 :(得分:25)
好吧,看来你已经发现为什么两者有差异,这是因为他们报告了不同的密度比例因素:
那么,为什么他们在技术上具有相同的物理尺寸和分辨率时会有不同的报告?
CORE问题确实存在,因为一个设备是Google Play设备(Nexus)而另一个设备不是(Kindle)。所有拥有Google Play(以及其他Google应用)的Android设备都只能通过称为兼容性测试套件(CTS)的功能来实现,该功能会验证此类设置是否符合他们提出的标准。标准本身记录在每个版本的兼容性定义文档(CDD)中。 Here is a link to the CDD for Android 4.0(第7.1节涉及屏幕尺寸和密度)。 CDD告诉设备制造商他们应该报告数字上最接近屏幕实际DPI的比例因子,在这种情况下实际上是TVDPI。
亚马逊设备不使用任何Google应用程序,包括Google Play。尽管遵循相同的标准可能符合他们的最佳利益,但它们并不受它们的约束,而且往往没有遵循。当它出现在Nexus 7上时,TVDPI就会向所有人嗤之以鼻,但亚马逊如果在设计中引用了CDD,就会知道它。
这是如何导致他们表现不同的?
差异不在您的布局选择中。显然,从您的屏幕截图中,两个设备都正在按照您的预期选择正确的布局。更改布局目录上的sw
值只影响哪些设备将选择该布局...它不会改变任何有关如何缩放的内容。不要试图将布局本身放在密度特定的目录中......布局应该是灵活的。
相反,问题在于在与密度无关的像素单位(即dip或dp)上进行的任何尺寸或大小计算,例如文本大小,您可能创建的任何固定视图尺寸以及可绘制尺寸。
由于这两个设备具有选择以不同方式扩展资源,因此您使用的任何可绘制资源或您在“dp”中定义的任何值都将导致较小的更改。让我举两个例子:
您可以将TextView
的文字大小定义为16dp
。在Nexus 7上,这将以21px的速度绘制文本。 Kindle Fire HD将以24px的速度绘制相同的文本。差异很小......但它存在。
可绘图像也是如此。如果你只在48x48的drawable-mdpi
和72x72的drawable-hdpi
中定义了相同的图像,那么Kindle可以直接使用72px的图像,而Nexus会创建一个64px的图像,所以有一个两个资产之间的差异为8个像素。
如何让两者看起来更相似?
在大多数情况下,我会说你不应该这样做。通常,完成缩放不会对应用程序的结果产生很大影响,除非布局的约束设置了太多硬编码的大小。
但是,一般情况下,如果您需要为此目的专门更改UI的某些部分,解决方案是为您认为需要的-tvdpi
案例定义特定资源和维度(同样,我不建议在您的应用中扩展所有内容以满足此情况。)
对于文本或视图大小等内容,这意味着您可能需要values-tvdpi/dimensions.xml
文件和默认values/dimensions.xml
文件。使用上面的示例,您可以将默认文本大小定义为16dp,但在-tvdpi
位置,定义与18dp相同的维度。这将导致两个设备将最终文本缩放到24px。在使用实际维度的代码中,请直接将其引用为@dimen/myTextSize
而不是16dp
。
对于可绘制项目,添加drawable-tvdpi
目录并缩放这些资源以匹配您认为应该在Nexus 7等设备上绘制的内容。再次使用前面的示例,从{{1}复制相同的图像文件}}}文件夹进入drawable-hdpi
文件夹,这样两个设备都会在72px处绘制相同的图像。
为避免在多个位置复制同一资产,您也可以使用别名来执行此操作。将图片本身放入drawable-tvdpi
并使用特殊名称,并使用drawable/
和values-tvdpi/drawables.xml
在两个位置引用单个资源。有关别名的更多信息,请see this documentation。这些示例适用于布局,但相同的范例适用于drawable(或任何资源),方法是更改为values-hdpi/drawables.xml
。
答案 1 :(得分:1)
由于Nexus7是tvdpi设备,它使用layout-sw600dp资产(基于213dpi的计算),FireHD是一个HDPI设备,最终使用layout-sw533dp资产(基于240dpi的计算)
答案 2 :(得分:1)
也许你应该使用layout-tvdpi和layout-hdpi?