getDimension()/getDimensionPixelSize() - mutliplier issue

后端 未结 5 1086
悲哀的现实
悲哀的现实 2021-02-07 06:07

So I have android 2.3.5 device which is NORMAL/HDPI. I have a dimens.xml in my project:

...
    20sp         


        
相关标签:
5条回答
  • 2021-02-07 06:23

    Because... NORMAL is NOT hdpi...
    Normal is mdpi (160dpi) = 1.0x.
    hdpi (240dpi) is 1.5x.
    xhdpi (320dpi) is 2.0x.
    xxdpi (480dpi) is 3.0x.
    xxxhdpi (640dpi) is 4.0x.
    And (last, but not least) ldpi (120dpi) is 0.75x.

    0 讨论(0)
  • 2021-02-07 06:26

    Per the Supporting Different Screen Densities training, hdpi is 1.5x normal (mdpi) sizes. As getDimensionPixelSize takes this difference into account when converting into pixels, the returned value will be 1.5x your value in sp.

    Note that sp is also dependent on the user's preferred text size and can therefore change to be even larger than 1.5x your expected value.

    0 讨论(0)
  • 2021-02-07 06:32

    If someone else needs this :

    To address the double scaling problem Stan show when using getDimensionPixelSize with TextView.setTextSize :

    You can use the alternate version of setTextSize where you can specify the unit like this :

    title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.title));
    
    0 讨论(0)
  • 2021-02-07 06:37

    Just to clarify (information obtained by inspecting Android source code):

    Resources.getDimension() and getDimensionPixelOffset()/getDimensionPixelSize() differ only in that the former returns float while the latter two return the same value rounded to int appropriately. For all of them, the return value is in raw pixels.

    All three functions are implemented by calling Resources.getValue() and converting the thus obtained TypedValue by calling TypedValue.complexToDimension(), TypedValue.complexToDimensionPixelOffset() and TypedValue.complexToDimensionPixelSize(), respectively.

    Therefore, if you want to obtain the "raw" value together with the unit specified in the XML source, call Resources.getValue() and use the methods of the TypedValue class.

    0 讨论(0)
  • 2021-02-07 06:45

    Method getDimension() converts dp or sp values into pixels based on current screen density. This is very useful as you don't have to do it on your own, when you want to set in Java width or text size (they accepts only pixels).

    But if you need original sp or dp you could do "reverse engineering".

    Step 1. Check current scale ratio (based on screen density):

    float scaleRatio = getResources().getDisplayMetrics().density;
    

    Step 2. Get dimension from dimens.xml

    float dimenPix = getResources().getDimension(R.dimen.your_dimen_name);
    

    Step 3. Do some math

    float dimenOrginal = dimenPix/scaleRatio;
    

    Remarks:

    • usually you need int for dimension methods (like setWidth()), so you have to convert float result to int for instance using Math.round()
    • more accurate result when rounding to int you could get using such formula (dimenPix-0.5f)/scaleRatio
    • in case of sp you could take also into account user preferences about text scale

    Read more about dimensions in Android: http://android4beginners.com/2013/07/appendix-c-everything-about-sizes-and-dimensions-in-android/

    0 讨论(0)
提交回复
热议问题