getDimension()/ getDimensionPixelSize() - mutliplier问题

Sta*_*tan 14 android dimensions textview

所以我有android 2.3.5设备,它是NORMAL/HDPI.我的项目中有一个dimens.xml:

...
    <dimen name="gameresult_congrats_label_msg_textSize">20sp</dimen>
...
Run Code Online (Sandbox Code Playgroud)

此文件在values-normal/values-hdpi等文件夹中完全相同.在我的第一个活动应用程序中使用以下方

Toast.makeText(this, "textSize is "+getResources().getDimensionPixelSize(R.dimen.gameresult_congrats_label_msg_textSize), Toast.LENGTH_SHORT).show();
Run Code Online (Sandbox Code Playgroud)

它显示了30.我也尝试过:

Toast.makeText(this, "textSize is "+getResources().getDimension(R.dimen.gameresult_congrats_label_msg_textSize), Toast.LENGTH_SHORT).show();
Run Code Online (Sandbox Code Playgroud)

但结果是一样的.但只有当我尝试这个时:

Toast.makeText(this, "textSize is "+getResources().getString(R.dimen.gameresult_congrats_label_msg_textSize), Toast.LENGTH_SHORT).show();
Run Code Online (Sandbox Code Playgroud)

我终于拿到了"20sp"!但那是为什么呢?官方文档称这些方法会返回

资源维度值乘以适当的度量标准.

我通过将我的值改为25来检查这个,我得到38,这意味着aos使用1.5乘数.但为什么?它已经从适当的文件夹中获取价值,这意味着它可以获得准备使用的价值!aos从那里获得1.5倍乘数?我知道这取决于DisplayMetrics.但它如何计算1.5倍?
更新
我理解乘数,但是,你知道,这里真正的问题是双重缩放.这就是为什么我问过这个问题.
所以如果我有一些layout.xml(在res\layout文件夹中),TexView定义如下:

<TextView
    android:id="@+id/congratsLabel"
    ...
    android:textSize="@dimen/gameresult_congrats_label_msg_textSize" />
Run Code Online (Sandbox Code Playgroud)

一切都很好看.我的意思是textview就像我期待的那样.
现在让我们在代码中做同样的事情:

TextView congratsLabel = fineViewById(R.id.congratsLabel); 
textSize = getResources().getDimension(R.dimen.gameresult_congrats_label_msg_textSize)
congratsLabel.setTextSize(textSize) 
Run Code Online (Sandbox Code Playgroud)

这是问题!!! getResources().getDimension()返回一个SCALED值,没关系.但是我的textView的结果大小将比我预期的大1.5,因为setTextSize与SP一起工作,这里是第二个尺度!这就是为什么AOS使得结果文本大小缩放到45(最初定义为20sp).

Jar*_*mec 24

只是为了澄清(通过检查Android源代码获得的信息):

Resources.getDimension()getDimensionPixelOffset()/ getDimensionPixelSize()区别仅在于前者返回float,而后两者返回相同的四舍五入到int适当的值.对于所有这些,返回值以原始像素为单位.

所有三个功能是通过调用实现Resources.getValue()和转换这样获得TypedValue通过调用TypedValue.complexToDimension(),TypedValue.complexToDimensionPixelOffset()TypedValue.complexToDimensionPixelSize()分别.

因此,如果要获取"原始"值以及XML源中指定的单位,请调用Resources.getValue()并使用TypedValue该类的方法.


小智 15

方法getDimension()根据当前屏幕密度将dp或sp值转换为像素.当你想要设置Java宽度或文本大小(它们只接受像素)时,这非常有用,因为你不必自己动手.

但如果你需要原始sp或dp,你可以做"逆向工程".

步骤1.检查当前比例比(基于屏幕密度):

float scaleRatio = getResources().getDisplayMetrics().density;
Run Code Online (Sandbox Code Playgroud)

步骤2.从dimens.xml获取维度

float dimenPix = getResources().getDimension(R.dimen.your_dimen_name);
Run Code Online (Sandbox Code Playgroud)

第3步.做一些数学运算

float dimenOrginal = dimenPix/scaleRatio;
Run Code Online (Sandbox Code Playgroud)

备注:

  • 通常你需要int作为维度方法(比如setWidth()),所以你必须将float结果转换为int,例如使用Math.round()
  • 当舍入到int时,你可以使用这样的公式(dimenPix-0.5f)/ scaleRatio更准确的结果
  • 如果是sp,您还可以考虑用户对文本比例的偏好

阅读有关Android中维度的更多信息:http://android4beginners.com/2013/07/appendix-c-everything-about-sizes-and-dimensions-in-android/


ian*_*ake 14

根据支持不同的屏幕密度训练,hdpi是1.5x正常(mdpi)大小.作为getDimensionPixelSize转换为像素时,采用此差异考虑在内,则返回值将是1.5倍于你的价值sp.

请注意,这sp也取决于用户的首选文本大小,因此可以更改为甚至大于预期值的1.5倍.


Ant*_*ine 6

如果其他人需要这个:

为了解决在使用带有TextView.setTextSize的getDimensionPixelSize时Stan显示的双缩放问题:

您可以使用setTextSize的备用版本,您可以在其中指定单位:

title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.title));
Run Code Online (Sandbox Code Playgroud)