Android Scaling & Density Issues

霸气de小男生 提交于 2019-12-31 04:52:08

问题


Update: Some research has turned up that the Asus Transformer TF700T (high end) should have a pixel density of about 224, so the values of 159 android is reporting are either erroneous, or have been modified somehow (the lcd-density key in /system/build.prop), which I can't find for some reason.

I have two near identical tablets I'm developing on, both ASUS Transformer's, and both 10.1".

The higher end model has the following specs (where 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

and the lower end model has:

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

The higher end model has a discrepency. The Density/DensityDpi is 1.5/High, which makes sense b/c of the high resolution within a 10.1" screen. But to get a value of 1.5, wouldn't Xdpi/Ydpi = 240, such that (for equation, see http://developer.android.com/guide/practices/screens_support.html)

px = dp * (dpi / 160) 

where

scale = (dpi / 160)

so

240/160 = 1.5 

Xdpi/Ydpi of 160 doesn't correspond to a 1.5 Density (scaling) factor, which would be 160/160 = 1, correct ?

This discrepancy between the DPI's and scaling factor is causing me some size mismatches between the two tablets, b/c the functions I'm using (Context.Resources.GetDimension) is scaling the values up too much on the higher end tablet (or too small on the lower end, depending on which I base the "normal/good" sizes on).

That is, I wouldn't have this problem if the Density was 1, or the xdpi/Ydpi was 240, on the first tablet. These values don't appear to be connected, as they should be. This may be because ASUS may have set the LCD-Density setting to 159, to obtain higher resolution (in /system/build.prop - I looked for the ro.sf.lcd_density key (with ROM Toolbox) to confirm but couldn't find it).


Here are some print outs for reference, from the custom view's constructor:

High end tablet:

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

Low end tablet:

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

where the view's layout declaration is

<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"/>

and the dimens it references are defined as

<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>

回答1:


Looks like you do something like I did. I mean you think that AOS chooses resources using DisplayMetrics but thats not true. There is also a Configuration. So for instance I was thinking that my HTC is HDPI for AOS since its really hdpi/240 by DisplayMetrics. But by Configuration its NORMAL. pls look at stackoverflow.com/questions/15837469/… maybe u'r gonna find it useful.
So maybe one of your tablets must use res/large-mdpi and the other res/large-hdpi.




回答2:


Note: I'm not accepting my own answered so that hopefully someone that knows what is going on with this will take a shot. I'm posting this answer b/c it did solve my problem, but still doesn't address some underlying questions and mysteries.


Well, after doing some calculations of my own, it looks as though the high-end device has more accurate Xdpi/Ydpi values, and the lower end device is reporting higher than calculated values. Both have physical dimensions of

length = 7.12"
width = 10.35"

so, we have for the high-end tablet

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

and for the low-end one

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

Asus documentation states that

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

I do realize that android "buckets" devices into 4 groups based on density: low, medium, high, very-high, and assigns the (abstract) dpi value (in /system/build.prop) with preset values based on these: 120, 160, 240, and 320 respectively.

Despite these values, android did correctly report the Density (scaling factor) for each, which was

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

So, as suggested by android (http://developer.android.com/guide/practices/screens_support.html) for supporting multiple screens, I made two Values folders for two versions of dimens.xml (where the size's were defined):

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

and adjusted the values accordingly, where Values-Hdpi/dimens.xml had smaller values to compensate for the 1.5 scaling factor, and Values-Mdpi/dimens.xml had "normalized" values that get scaled by 1. Both tablets now correctly display the correct sizes. But, isn't that what the dp/dip metric is for, so that these separate value sets do not need to be explicitly defined ?



来源:https://stackoverflow.com/questions/16679526/android-scaling-density-issues

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!