【问题标题】:How to use dimens.xml in Android?如何在 Android 中使用dimens.xml?
【发布时间】:2015-03-18 16:58:56
【问题描述】:

当我设计布局时,由于可维护性的主题,我将所有维度集中在 dimens.xml 中。我的问题是这是否正确。最好的做法是什么?这方面的信息很少,什么都没有。我知道将布局的所有字符串集中在strings.xml 上,将颜色集中在colors.xml 上是个好主意。但是关于尺寸?

例如:

<TableLayout
    android:id="@+id/history_detail_rows_submitted"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/cebroker_history_detail_rows_border"
    android:collapseColumns="*">

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/history_detail_rows_margin_vertical"
        android:background="@color/cebroker_history_detail_rows_background"
        android:gravity="center"
        android:paddingBottom="@dimen/history_detail_rows_padding_vertical"
        android:paddingLeft="@dimen/history_detail_rows_padding_horizontal"
        android:paddingRight="@dimen/history_detail_rows_padding_horizontal"
        android:paddingTop="@dimen/history_detail_rows_padding_vertical">

        <TextView
            android:layout_width="match_parent"
            android:drawableLeft="@mipmap/ic_history_detail_submitted_by"
            android:drawablePadding="@dimen/history_detail_rows_textviews_padding_drawable"
            android:gravity="left|center"
            android:paddingRight="@dimen/history_detail_rows_textviews_padding"
            android:text="@string/history_detail_textview_submitted_by"
            android:textColor="@color/cebroker_history_detail_rows_textviews"
            android:textSize="@dimen/history_detail_rows_textviews_text_size" />

【问题讨论】:

  • My question is if this is correct or not是的,是的。它应该以这种方式使用。
  • 在dimens.xml 中保留尺寸是正确的方法。但有时它太复杂了。我通常只在 dimen.xml 中保留我将针对不同屏幕尺寸更改的那些尺寸,或者为不同的视图共享它(默认填充、文本大小)
  • 我同意你的看法@VolodymyrBaydalka。当然,用超集中的方法维护一个dimens.xml 是非常困难的。很好地管理每个视图的文本大小。

标签: android android-layout


【解决方案1】:

如何使用dimens.xml

  1. 右键单击values 文件夹并选择新建> 值资源文件,创建一个新的dimens.xml 文件。写dimens作为名字。 (您也可以将其称为 dimendimensions。名称并不重要,只有 dimen 将包含的资源类型。)

  2. 添加dimen 名称和值。

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

    值可以是dppxsp

  3. 使用xml中的值

     <TextView
         android:padding="@dimen/my_value"
         ... />
    

    或在代码中

     float sizeInPixels = getResources().getDimension(R.dimen.my_value);
    

何时使用dimens.xml

感谢this answer 提供更多想法。

  1. 重用值 - 如果您需要在整个应用程序的多个位置使用相同的维度(例如,Activity 布局填充或 TextView textSize),那么使用单个 dimen 值将方便以后调整。这与使用样式和主题的想法相同。

  2. 支持多个屏幕 - 8dp 的填充在手机上可能看起来不错,但在 10 英寸平板电脑上却很糟糕。您可以创建多个 dimens.xml 以用于不同的屏幕。这样您可以为手机设置8dp,为平板电脑设置64dp。要创建另一个dimens.xml 文件,请右键单击res 文件夹并选择新建> 值资源文件。 (详见this answer

  3. 方便的dppx 代码转换 - 在代码中,您通常需要使用像素值。但是,您仍然需要考虑设备密度,而以编程方式执行 conversion 很烦人。如果你有一个恒定的dp 值,你可以像float 这样简单地以像素为单位:

     float sizeInPixels = getResources().getDimension(R.dimen.my_value);
    

    或者这个int

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

我在my fuller answer 中提供了有关如何执行这些操作的更多详细信息。

什么时候不使用dimens.xml

  • 不要将您的值放在dimens.xml 中,否则会使它们更难维护。一般来说,只要它不属于我上面列出的类别。使用dimens.xml 会使代码更难阅读,因为您必须在两个文件之间来回切换才能查看实际值。个人视图不值得(在我看来)。

  • 字符串不同。所有字符串都应该放在像strings.xml 这样的资源文件中,因为在国际化您的应用程序时几乎所有字符串都需要翻译。另一方面,大多数维度值不需要针对不同的位置进行更改。 Android Studio 似乎支持这种推理。直接在布局 xml 中定义字符串会发出警告,但定义 dp 值不会。

【讨论】:

  • 您如何确定将来不会使用哪个值?!那不是很难,甚至是不可能的。
  • 我认为假设是现在做一个最好的猜测,如果碰巧将来其他地方需要这个值,那么你可以在那个时候把它拉到一个维度文件中。跨度>
【解决方案2】:

添加一个用于支持多个设备的 xml 文件 dimens.xml。

 <resources>
 <!-- Default screen margins, per the Android Design guidelines. -->
  <dimen name="iconarrow">1dp</dimen>
  <item name="text_view_padding" type="integer">100</item>
</resources>

然后你可以在你的代码中使用它,就像在 java 代码中一样

textview.setPadding(0, 0, 0, getResources().getInteger(R.integer.text_view_padding));

您也可以在其他布局(xml文件)中使用。

android:padding="@dimen/text_view_padding"

【讨论】:

  • 谢谢伙计。但是,我想知道哪种方法更好地管理或维护 dimens.xml 文件。
【解决方案3】:

您不需要在值文件夹文件中提及维度值。这个库会自动管理你刚才调用的所有东西

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/_20sdp"
android:paddingLeft="@dimen/_20sdp"
android:paddingRight="@dimen/_20sdp"
android:paddingTop="@dimen/_20sdp"
android:background="@color/colorPrimary"
android:orientation="vertical"
 >

whole code click here for that

【讨论】:

    【解决方案4】:
    But about dimensions?
    

    根据官方 Android 文档“维度是一个简单的资源,它使用 name 属性中提供的值(不是 XML 文件的名称)来引用。因此,您可以将维度资源与其他简单的一个 XML 文件中的资源,在一个 &lt;resources&gt; 元素下"

    更多详情请参考http://developer.android.com/guide/topics/resources/more-resources.html

    在这篇文章中,Devunwired 给出了为什么使用dimens.xml When should the dimens.xml file be used in Android?的三个重要理由

    【讨论】:

      【解决方案5】:

      @Jesús Castro 你做得对。在 dimens.xml 文件中维护值比在所有布局文件中乱扔硬编码值更好。

      例如,想象一下您在所有视图中增加左右边距的情况。如果您使用在 dimens.xml 中维护的单个值,这将是一个快速更改 - 单个文件中的单个值。 但是,如果您在布局文件中将边距值作为文字值(例如“16dp”)(而不是使用“@dimen/leftright_margin”之类的尺寸值),则必须编辑每个容易出错的布局文件而且很费时间。

      【讨论】:

        【解决方案6】:

        我有一个我认为符合问题的新颖方法。我一直在避免使用 Xml 以避免解析 xml 代码的成本。

        我没有使用 xml 维度,而是使用 java 常量。 要么……

        public interface DimenConstants { ... }
        

        或者...

        public class DimenConstants
        {
            public static void init(Activity activity){...}
        }
        

        那么在支持不同屏幕的情况下,实际上你可以在运行时在Java中自己做这个。一种方法是:

        public class TestScreenSizes extends Activity
        {
            public static final ViewGroup.LayoutParams MAIN_VIEW_SPEC = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        
            @Override protected void onCreate(Bundle savedState)
            {
             super.onCreate(savedState);
             setContentView(newTextView(),MAIN_VIEW_SPEC);
            }
        
            protected TextView newTextView()
            {
             TextView tv = new TextView(this);
             DisplayMetrics display = getResources().getDisplayMetrics();
        
             int resolution = display.widthPixels * display.heightPixels;
        
             if(resolution == 1024) tv.setText("You are using an iphone");
             else if(resolution == 4096) tv.setText("You are using a Samsung Galexy");
        
             return rv;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2015-12-17
          • 1970-01-01
          • 2011-11-22
          • 1970-01-01
          • 1970-01-01
          • 2016-04-22
          • 1970-01-01
          • 2015-12-27
          • 1970-01-01
          相关资源
          最近更新 更多