在Android中,什么时候应该使用dimens.xml文件?

19

比如,在一个特定的布局中,我有以下XML:

<GridView
    android:id="@+id/gridView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="3dp"
    android:columnWidth="48dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="spacingWidth" />

这个网格视图是针对这个布局特定的,我不认为我会使用任何其他具有类似属性的网格视图。也就是说,代码中的尺寸值是特定于该网格视图的。

我是否应该将它们移动到dimens.xml文件中,还是只需保留它们就可以了?如果是这样,那么当该值在多个布局中使用时,我应该将值放在dimens.xml文件中吗?

4个回答

35

我通常会将维度值放入dimens.xml资源中,主要有以下三个原因:

  1. 重复使用:我需要多个小部件或布局使用相同的值,并且只想在整个应用程序更新或调整时更改一次。

  2. 密度差异:如果我需要从ldpi->hdpismall->large使维度略微变小或变大。

  3. 从代码中读取:当我在代码中实例化视图并希望应用一些静态尺寸时,将它们放入 dimens.xml 作为 dp (或 dip ),可以使用 Resources.getDimensionPixelSize() 在Java代码中获取缩放值。


关于第二个问题,在dimens.xml文件中如何进行区分(如果可能,请提供示例)?第三个原因非常有说服力。 - rfgamaral
@Nazgulled 在合格的目录中使用多个文件。例如,在res/values中放置一个dimens.xml用于默认值,另一个在res/values-ldpi中包含我想要覆盖低密度设备的一些内容。 - devunwired
@Devunwired,你是否遇到过高密度设备引用values-ldpi/dimens.xml文件的问题?我在使用三星Galaxy Note时遇到了这个问题 - 它使用了values-ldpi/dimens.xml中定义的尺寸,而不是values-xxhdpi/dimens.xml或values-hdpi/dimens.xml中定义的尺寸。有什么建议吗? - marienke
@Enke 我在Note上没有遇到过这个问题。它是一个hdpi设备,通常会选择正确的资源。 - devunwired
@Devunwired,最终我通过删除自定义values-sw320dpi文件夹中的dimen元素,并添加所有缺失的具有各种尺寸的元素来解决问题,现在我有/res/values;/values-ldpi、/values-mdpi、/values-hdpi、/values-xhdpi、/values-small、/values-large和/values-xlarge,这似乎可以工作。 - marienke
显示剩余3条评论

23

补充回答

@Devunwired列举了使用dimens.xml的3个原因。以下是如何实现这些细节。

1. 重用

如果你在dimens.xml中设置一些dpsp值,例如:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="textview_padding">16dp</dimen>
    <dimen name="large_text_size">30sp</dimen>
</resources>

你可以在应用程序的多个地方重复使用它。

<TextView
    android:padding="@dimen/textview_padding"
    android:textSize="@dimen/large_text_size"
    ... />

<TextView
    android:padding="@dimen/textview_padding"
    android:textSize="@dimen/large_text_size"
    ... />

当您需要进行更改时,只需要在一个地方进行即可。

注释

  • 这基本上与使用样式或主题的效果相同。
  • 如果您不小心给两个不应该有相同dimen值的视图赋予了相同的值,那么如果您需要对其中一组视图进行更改而不对另一组视图进行更改,则必须逐个返回每个视图,这将破坏其目的。

2. 大小差异

  • @ Devunwired 称此为密度差异,但如果您使用dp(密度无关像素),则除最小情况外,它已经解决了所有密度差异问题。因此,在我看来,屏幕大小是使用dimens.xml的更重要因素。

8dp填充在手机上可能看起来很好,但在平板电脑上运行应用程序时,它看起来太窄了。您可以通过制作两个(或更多)不同版本的dimens.xml来解决此问题。

右键单击您的res文件夹,选择新建>值资源文件。然后输入dimens并选择最小屏幕宽度。键入宽度的值600(7英寸平板电脑)。 (有其他选择大小的方法。请参见文档此答案以获取更多信息。)

enter image description here

这将创建另一个values文件夹,该文件夹将用于其最小屏幕宽度为600dp的设备。在Android视图中,这两个dimens.xml文件如下所示。

enter image description here

现在您可以独立修改它们。

values/dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="my_default_padding">16dp</dimen>
</resources>

values-sw600dp/dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="my_default_padding">64dp</dimen>
</resources>

使用 dimen 时,您只需使用在两个 dimens.xml 文件中使用的名称设置即可。

<LinearLayout
    ...
    android:padding="@dimen/my_default_padding">

</LinearLayout>

系统将根据用户使用的设备自动为您选择正确的值。

3. 从代码读取

有时在pxdp之间进行程序化缩放可能很麻烦(请参见此答案)。

如果您已经在dimens.xml中定义了一个固定的dp值,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="my_dp_value">16dp</dimen>
</resources>

然后您可以轻松获取它,只需要

int sizeInPixels = getResources().getDimensionPixelSize(R.dimen.my_dp_value);

并且它将已经转换为像素,以适应用户所使用的任何密度设备。


这很有帮助。你知道强制 Android Studio 在布局预览期间选择特定的dimens.xml文件的方法吗?我在设置三星S7横向文件时遇到了麻烦 - 我已经创建了一个sw640dp值文件,但预览仍然选择默认文件。 - orion elenzil
@orionelenzil,我不知道关于布局预览的情况。你可以尝试提出一个新问题来询问这个问题。我会说sw600dpsw640dp更标准。这是最小宽度,所以600将包括640和任何其他更大的尺寸。此外,只要在模拟器或设备中运行应用程序时获得正确的尺寸,我认为预览无法工作并不重要。 - Suragch
感谢@Suragch。我在这里发布了一个新问题链接 - orion elenzil

4
< p > dimens.xml 文件用于将所有硬编码的像素值放在一个地方。

< p > 现在,尽管您现在可能不会重复使用这些值,但将它们放置在 dimens.xml 中以备将来参考仍然是一个好主意。此外,遵循标准的 Android 编程范例有助于其他开发人员更快地理解您的代码。这很像我们放置 Stringstrings.xml,其中一些只被使用一次! :)


2
这并不完全相同,字符串XML文件还允许国际化,因此将它们与代码分开更有意义。 - rfgamaral
1
那是什么样的评论? - rfgamaral
抱歉如果我表达不清楚。我的意思是,你的评论并没有真正帮助原帖的问题,也不完全与我的帖子相关。我只是说实话! :) - Sagar Hatekar
1
实际上这是相关的,而且很有用。这就是为什么我投票支持他的评论。此外,他还是问题的发布者。问他是否有更好的答案对于他自己的问题来说有点无意义。请不要误解客观批评。这只是一个有效的、建设性的侧记,没有任何个人恶意。 :) - user658042

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接