【问题标题】:Android Scaling & Density IssuesAndroid 缩放和密度问题
【发布时间】:2013-05-21 21:09:36
【问题描述】:

更新: 一些研究表明,华硕 Transformer TF700T(高端)的像素密度应该约为 224,因此 android 报告的 159 值要么是错误的,要么是以某种方式修改(/system/build.prop 中的 lcd-density 键),由于某种原因我找不到。

我正在开发两台几乎完全相同的平板电脑,都是华硕 Transformer 和 10.1"。

高端模型具有以下规格(其中 dm = ApplicationContext.Resources.DisplayMetrics):

dm.Density = 1.5
dm.DensityDpi = High
dm.WidthPixels = 1920
dm.HeightPixels = 1128
dm.Xdpi = 159.8951
dm.Ydpi = 159.5811

低端型号有:

dm.Density = 1
dm.DensityDpi = Default
dm.WidthPixels = 1280
dm.HeightPixels = 752
dm.Xdpi = 160.1576
dm.Ydpi = 160

高端型号存在差异。 Density/DensityDpi 是 1.5/High,这对于 10.1" 屏幕内的高分辨率来说是有意义的。但要获得 1.5 的值,Xdpi/Ydpi = 240 不会,这样 (方程式见http://developer.android.com/guide/practices/screens_support.html

px = dp * (dpi / 160) 

在哪里

scale = (dpi / 160)

所以

240/160 = 1.5 

160 的 Xdpi/Ydpi 不对应于 1.5 的密度(缩放)因子,即 160/160 = 1,对吗?

DPI 和缩放因子之间的这种差异导致我在两个平板电脑之间出现一些尺寸不匹配, b / c我正在使用的功能(Context.Resources.GetDimension)在高端平板电脑上将值放大太多(或者在低端平板上太小,这取决于我将“正常/好”尺寸基于哪个)。

也就是说,如果第一台平板电脑上的密度为 1,或者 xdpi/Ydpi 为 240,我就不会遇到这个问题。这些值似乎没有联系,因为它们应该是。这可能是因为华硕可能已将 LCD-Density 设置为 159,以获得更高的分辨率(在 /system/build.prop - 我寻找 ro.sf.lcd_density 键(使用 ROM 工具箱)以确认但无法找到它)。


这里有一些打印输出供参考,来自自定义视图的构造函数:

高端平板电脑:

Context.Resources.GetDimension(control_panel_height_id) = 75
Context.Resources.GetDimension(grid_cell_boarder_width_id) = 1.5
Context.Resources.GetDimension(list_title_height_id) = 40.5
Context.Resources.GetDimension(list_title_text_size_id) = 21
Context.Resources.GetDimension(list_item_text_size_1_id) = 18
Context.Resources.GetDimension(list_item_text_size_2_id) = 15
Context.Resources.GetDimension(month_label_text_size_id) = 33

低端平板电脑:

Context.Resources.GetDimension(control_panel_height_id) = 50
Context.Resources.GetDimension(grid_cell_boarder_width_id) = 1
Context.Resources.GetDimension(list_title_height_id) = 27
Context.Resources.GetDimension(list_title_text_size_id) = 14
Context.Resources.GetDimension(list_item_text_size_1_id) = 12
Context.Resources.GetDimension(list_item_text_size_2_id) = 10
Context.Resources.GetDimension(month_label_text_size_id) = 22

视图的布局声明在哪里

<AppName.Droid.Views.Custom.CustomView
  xmlns:calendar="http://schemas.android.com/apk/res/namespace"
  android:id="@+id/CustomView1"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#1100FF00"
  calendar:control_panel_height="@dimen/control_panel_height"
  calendar:grid_cell_boarder_width="@dimen/grid_cell_boarder_width"
  calendar:list_title_height="@dimen/list_title_height"
  calendar:list_title_text_size="@dimen/list_title_text_size"
  calendar:list_item_text_size_1="@dimen/list_item_text_size_1"
  calendar:list_item_text_size_2="@dimen/list_item_text_size_2"
  calendar:month_label_text_size="@dimen/month_label_text_size"/>

它引用的维度被定义为

<resources>
  <dimen name="control_panel_height">50dip</dimen>
  <dimen name="grid_cell_boarder_width">1dip</dimen>
  <dimen name="list_title_height">27dip</dimen>
  <dimen name="list_title_text_size">14dip</dimen>
  <dimen name="list_item_text_size_1">12dip</dimen>
  <dimen name="list_item_text_size_2">10dip</dimen>
  <dimen name="month_label_text_size">22dip</dimen>
</resources>

【问题讨论】:

  • 你计算错了。对于高端,1920 / 160 = 12,即 12 英寸。除以 1.5(密度乘数)得出 8 英寸的宽度。对于低端,1280 / 160 = 8 英寸,除以 1 = 8 英寸。对高度做同样的事情,使用毕达哥拉斯定理,你得到一个 10 英寸的对角线。对于您的具体问题,我不明白您为什么会遇到问题,但我一直依赖WindowManager。我从未使用过Resources.GetDimension
  • @Simon 他们都是 10.1"(添加到 OP)。另外,我没有做任何计算,只是阅读 ApplicationContext.Resources.DisplayMetrics 数据结构。正如你所建议的,我可能应该'不使用 Resources.GetDimension; 我将直接从视图的构造函数中引用维度,而不是将它们分配为布局文件中的 xml 属性(然后必须读取属性,这是我的问题出现的地方),因为我是如何在应用程序的其他部分进行的,没有大小不匹配的问题(我一夜之间就意识到了)。感谢您的评论,它确实帮助了我。

标签: android xamarin.android


【解决方案1】:

看起来你做的事情和我一样。我的意思是您认为 AOS 使用 DisplayMetrics 选择资源,但事实并非如此。还有一个配置。例如,我认为我的 HTC 是适用于 AOS 的 HDPI,因为它实际上是 DisplayMetrics 的 hdpi/240。但通过配置其正常。 pls look at stackoverflow.com/questions/15837469/… 也许你会发现它很有用。
所以也许你的一个平板电脑必须使用 res/large-mdpi 和另一个 res/large-hdpi。

【讨论】:

    【解决方案2】:

    注意:我不接受我自己的回答,希望知道这是怎么回事的人会采取行动。我发布这个答案 b/c 它确实解决了我的问题,但仍然没有解决一些潜在的问题和谜团。


    好吧,在我自己做了一些计算之后,看起来高端设备的 Xdpi/Ydpi 值更准确,而低端设备报告的值高于计算值。两者的物理尺寸均为

    length = 7.12"
    width = 10.35"
    

    所以,我们有高端平板电脑

    Xdpi = 1920 / 10.35 = 185.5
    Ydpi = 1128 / 7.12 = 158.4
    

    对于低端的

    Xdpi = 1280 / 10.35 = 123.7
    Ydpi = 752 / 7.12 = 105.6
    

    华硕文档指出

    dpi (high-end) = 224
    dpi (low-end) = 149
    

    我确实意识到 android “buckets” 设备根据密度分为 4 组:low、medium、high、very-high,并分配(抽象)dpi值(在 /system/build.prop 中)具有基于这些的预设值:分别为 120、160、240 和 320

    尽管有这些值,android 确实正确地报告了每个的密度(缩放因子),这是

    Density (high-end) = 1.5
    Density (low-end) = 1
    

    因此,正如 android (http://developer.android.com/guide/practices/screens_support.html) 为支持多屏幕所建议的那样,我为两个版本的 dimens.xml(定义了大小)创建了两个 Values 文件夹:

    Resources/Values-Hdpi/dimens.xml
    Resources/Values-Mdpi/dimens.xml
    

    并相应地调整了值,其中 Values-Hdpi/dimens.xml 具有较小的值以补偿 1.5 比例因子,而 Values-Mdpi/dimens.xml 具有“标准化”值,按 1 比例缩放。现在两款平板电脑正确显示正确的尺寸。 但是,这不是 dp/dip 指标的用途,因此不需要明确定义这些单独的值集吗?

    【讨论】:

    • 试试您可以在 PlayMarket 上找到的 ScreenInfo 应用程序(带有黄色图标)。看起来你做的事情和我一样。我的意思是您认为 AOS 使用 DisplayMetrics 选择资源,但事实并非如此。还有一个配置。例如,我认为我的 HTC 是适用于 AOS 的 HDPI,因为它实际上是 DisplayMetrics 的 hdpi/240。但通过配置其正常。请查看stackoverflow.com/questions/15837469/… 也许你会发现它很有用。所以也许你的一个平板电脑必须使用 res/large-mdpi 和另一个 res/large-hdpi。
    • @Stan 是的,听起来您遇到了完全相同的问题,感谢您的链接...“所以也许您的一台平板电脑必须使用 res/large-mdpi 和另一个 res/large-hdpi ",是的,上面的解决方案准确地说明了我是如何解决这个问题的。在您链接的帖子中,声明“android 仅作为 MDPI 威胁我的设备”可以使用 ApplicationContext.Resources.DisplayMetrics.Density 或 ApplicationContext.Resources.DisplayMetrics.DensityDpi 进行量化(打印出来查看... Density = 1 & DensityDpi = Mdpi 设备的“正常”)。谢谢。
    • 然后我会发布它作为答案
    猜你喜欢
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多