【问题标题】:When should the dimens.xml file be used in Android?什么时候应该在 Android 中使用dimens.xml 文件?
【发布时间】:2011-11-22 10:28:42
【问题描述】:

例如,在特定布局中,我有以下 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 文件中?

【问题讨论】:

    标签: android android-layout dimensions


    【解决方案1】:

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

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

    2. 密度差:如果我需要尺寸比ldpi -&gt; hdpismall -&gt; large 稍小或稍大。

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

    【讨论】:

    • 关于#2,你如何区分dimens.xml 文件(如果可能,请提供示例)?理由 3 很有说服力。
    • @Nazgulled 限定目录中的多个文件。例如,将dimens.xml 放入res/values 作为默认值,将另一个放入res/values-ldpi,其中包括我想为低密度设备覆盖的少数几个。
    • 我虽然这仅适用于 drawables 文件夹。感谢您的提示。
    • 不客气。限定符在所有资源目录上都是可用的(并且非常有用)。如果您查看 AOSP 代码,您会发现他们自己也大量使用了这个代码!
    • @Devunwired,您是否遇到过高密度设备引用 values-ldpi/dimens.xml 文件的问题?我在使用三星 Galaxy Note 时遇到了这个问题 - 它使用 values-ldpi/dimens.xml 中定义的尺寸,而不是 values-xxhdpi/dimens.xml 或 values-hdpi/dimens.xml 中定义的尺寸有什么建议吗?跨度>
    【解决方案2】:

    补充答案

    @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 并选择Smallest Screen Width。输入 600 作为宽度(7 英寸平板电脑)。 (还有其他选择尺寸的方法。请参阅documentationthis answer 了解更多信息。)

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

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

    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 之间以编程方式扩展的痛苦(请参阅this answer 了解如何)。

    如果你已经在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 值文件,但预览选择了默认值。
    • @orionelenzil,我不知道布局预览。你可以试着问一个关于这个的新问题。我会说sw600dp 是比sw640dp 更标准的设置。这是最小的宽度,所以600 将包括640 和任何其他更大的尺寸。此外,只要您在模拟器或设备中运行应用程序时获得正确的尺寸,我认为预览不起作用并不重要。
    • 感谢@Suragch。我发布了一个新问题here
    【解决方案3】:

    dimens.xml 文件用于将所有硬编码的像素值保存在一个位置。

    现在,尽管您现在可能不会重复使用这些值,但最好将它们放在 dimens.xml 中以供将来参考。此外,遵循标准的Android 编程范式有助于其他开发人员更快地理解您的代码。这很像我们放置Strings 的strings.xml,其中一些最终只使用一次! :)

    【讨论】:

    • 这不是一回事,字符串 XML 文件也允许国际化,因此将它们与代码分开更有意义。
    • 这是什么评论?
    • 对不起,如果我没有说清楚。我的意思是,您的 cmets 并没有真正帮助原始帖子的问题,也与我的帖子完全相关。我只是说实话! :)
    • 其实是相关的,有用的。这就是为什么我投票赞成他的评论。此外,他是这个问题的海报。问他是否对自己的问题有更好的答案是毫无意义的。请不要以错误的方式接受客观的批评。这只是一个有效的、建设性的旁注,没有什么私人的。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多