Android getDimension()/getDimensionPixelSize()-多个问题

Android getDimension()/getDimensionPixelSize()-多个问题,android,textview,dimensions,Android,Textview,Dimensions,所以我有android 2.3.5设备,它是普通的/HDPI。我的项目中有一个dimens.xml: ... <dimen name="gameresult_congrats_label_msg_textSize">20sp</dimen> ... 它显示30。我也试过: Toast.makeText(this, "textSize is "+getResources().getDimension(R.dimen.gameresult_congrats_labe

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

...
    <dimen name="gameresult_congrats_label_msg_textSize">20sp</dimen>
...
它显示30。我也试过:

Toast.makeText(this, "textSize is "+getResources().getDimension(R.dimen.gameresult_congrats_label_msg_textSize), Toast.LENGTH_SHORT).show();
但结果是一样的。但只有当我试着这样做的时候:

Toast.makeText(this, "textSize is "+getResources().getString(R.dimen.gameresult_congrats_label_msg_textSize), Toast.LENGTH_SHORT).show();
我终于拿到了20便士!但为什么呢?返回

资源维度值乘以适当的度量

我通过将我的值更改为25来检查这一点,得到38,这意味着aos使用1.5倍的乘数。但是为什么呢?它已经从适当的文件夹中获得了值,这意味着它获得了一个随时可用的值!aos从哪里得到1.5倍的乘数?我知道这取决于显示指标。但是它是如何计算1.5倍的呢?
更新
我理解乘法器,但是,你看,这里真正的问题是双重缩放。这就是我问这个问题的原因。
因此,如果我有一些layout.xml(在res\layout文件夹中)和TexView的定义如下:

<TextView
    android:id="@+id/congratsLabel"
    ...
    android:textSize="@dimen/gameresult_congrats_label_msg_textSize" />
问题就在这里!!!getResources().getDimension()返回一个缩放的值,这样就可以了。但是我的textView的结果大小将比我预期的大1.5,因为setTextSize与SP一起工作,这里是第二个刻度!这就是为什么AOS将生成的文本大小缩放为45(最初定义为20sp)

根据,hdpi是正常(mdpi)尺寸的1.5倍。由于
getDimensionPixelSize
在转换为像素时考虑了这一差异,因此返回的值将是
sp
中值的1.5倍

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

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

但如果您需要原始sp或dp,您可以进行“反向工程”

第1步。检查电流比例(基于屏幕密度):

float scaleRatio = getResources().getDisplayMetrics().density;
第2步。从dimens.xml获取维度

float dimenPix = getResources().getDimension(R.dimen.your_dimen_name);
第3步。做些数学题

float dimenOrginal = dimenPix/scaleRatio;
备注:

  • 通常,维度方法需要int(如setWidth()),因此必须使用Math.round()将浮点结果转换为int
  • 使用这样的公式(dimenPix-0.5f)/scaleRatio,四舍五入到int时,可以得到更精确的结果
  • 对于sp,您还可以考虑用户对文本比例的偏好

阅读更多关于Android中维度的信息:

,因为。。。正常不是hdpi…
正常是mdpi(160dpi)=1.0x。
hdpi(240dpi)是1.5x。
xhdpi(320dpi)是2.0x。
xxdpi(480dpi)是3.0x。
xxxhdpi(640dpi)是4.0x。
最后,但并非最不重要的是,ldpi(120dpi)是0.75x。

如果其他人需要:

要解决Stan show在将getDimensionPixelSize与TextView.setTextSize一起使用时出现的双重缩放问题,请执行以下操作:

您可以使用setTextSize的替代版本,在该版本中,您可以指定如下单位:

title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.title));
只是澄清一下(通过检查Android源代码获得的信息):

Resources.getDimension()
getDimensionPixelOffset()
/
getDimensionPixelSize()
的不同之处在于前者返回
float
,而后两者返回相同的值,并相应地四舍五入到
int
。对于所有这些对象,返回值均以原始像素为单位

这三个函数都是通过调用
Resources.getValue()
来实现的,并分别通过调用
TypedValue.complexToDimension()
TypedValue.complexToDimensionPixelOffset()
TypedValue.complexToDimensionPixelSize()
来转换由此获得的
TypedValue.complexToDimensionPixelSize()


因此,如果您希望获得“原始”值以及XML源中指定的单位,请调用
Resources.getValue()
并使用
TypedValue
类的方法。

aos是否不管是否使用相应的值文件夹都会这样做?比如,如果aos从hdpi值中获取值,为什么它仍然将其乘以1.5来获取hdpi值?或者,如果hdpi值中确实存在dimens.xml,为什么不在不进行任何后期转换的情况下使用它?@Stan-dp或sp中的维度在转换为像素时总是按比例缩放(这就是它们的用途)。这确保了文本的物理大小在每个设备上完全相同,而不管屏幕密度如何(mdpi上的物理英寸为20px==hdpi上的物理英寸为30px)。当然,您可以用像素(即20px)构建尺寸,但这意味着您的文本在xhdpi设备上非常小,而在ldpi设备上非常大,这几乎从来都不是您想要的。是的,但getDimension()为什么要这样做?我只想做一件事:按原样获取维度值。比如如果它是20sp,我希望得到20而不是20x1.5像素。因为我想在view.setTextSize()这样的方法中使用它,它接受作为SP而不是像素处理的值。这就是问题所在。因为在这个方法中我使用了20,一切看起来都很好,但是当我尝试使用getDimension(不是getDimensionPixelSize)获取值,并且AOS返回30时,文本变得太大。可能我的问题是我认为getResources().getDimension()从维度文件返回原始值,但它返回像素大小(如测量)值而不是原始值。旧的post但边点-setTextSize不接受被视为SP的值。如果使用setTextSize(TypedValue.COMPLEX_TYPE_PX,textSize),则它将起作用。你看,这里的问题是关于双重缩放。如果我在代码中创建了一些标签,并且我希望为其文本使用定义的大小,我会使用类似于
textSize=getResources().getDimension(R.dimen.gameresult\u恭喜\u label\u msg\u textSize)
的东西,并返回一个缩放值。现在,如果使用myLabel.setTextSize(textSize)
设置它,结果大小将比我需要的大1.5,因为
float dimenOrginal = dimenPix/scaleRatio;
title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.title));