8 minutes read

In this topic, we will talk about a folder that you will use when building your app: res/values. We will see where it is needed, what can be stored there, and how to work with it. With its help, you can assign color, size, font, and text to the elements. This folder is intended for storing resources of various types.

Specifically, in this topic, we will cover working with strings, colors, styles, and dimens files.

Strings

String resources are indicated by the tag <string>. It is suggested to store string resources in a strings.xml file, but you can use multiple files. The file structure for string resources is pretty simple: there is a root tag <resources> followed by one or more <string> child elements. Each <string> element has a "name" property and a value:

<resources>
   <string name="app_name">Android</string>
   <string name="btn_text">Click Me</string>
   <string name="btn_action">Send Me</string>
</resources>

If you create several files with resources, make sure that the created names are unique. Note that with resources of the same type and the same name, Android Asset Packaging Tool (aapt) will not compile. The aapt tool parses, indexes, and compiles the resources into the binary format optimized for the Android platform.

Colors

To work with color, you might need to brush up on the rgb and cmyk formats. Use the tag <color> to specify different colors and shades. You can use one of the following formats and values:

  • #RGB
  • #RRGGBB
  • #ARGB
  • #AARRGGBB
<resources>
   <color name="colorPrimary">#6200EE</color>
   <color name="colorPrimaryDark">#3700B3</color>
   <color name="colorAccent">#03DAC5</color>
   <color name="green_lime">#CDDC39</color>
   <color name="indigo">#3F51B5</color>
</resources>

There are also predefined color names whose identifiers are available in the android.R.color namespace:

val color: Int = resources.getColor(android.R.color.red)

You can find other color names in the Android documentation. Here is how you can use colors in any XML resource file:

<TextView  
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/app_description"
    android:textColor="@color/indigo"
    android:background="@android:color/black"/>

Styles and themes

Style resources help you maintain a consistent look for your application. A style is a set of attributes that control the appearance and behavior of a View. They are stored in the styles.xml or themes.xml files.

Specifying a style attribute for a View tag applies the style's attribute values to the View.

<!-- styles.xml -->
<resources>
    <style name="GreenPadded">
        <item name="android:background">@android:color/holo_green_light</item>
        <item name="android:padding">8dp</item>
    </style>
</resources>

<!-- layout -->
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    style="@style/GreenPadded" />

A theme is a style applied to a certain scope: a container, activity, or application. In the example below, the theme affects the appearance of a TextView inside the FrameLayout:

<!-- styles.xml -->
<resources>
    <style name="GreenPadded">
        <item name="android:background">@android:color/holo_green_light</item>
        <item name="android:padding">8dp</item>
    </style>
    <style name="BigCenteredText">
        <item name="android:textSize">34sp</item>
        <item name="android:gravity">center</item>
    </style>
</resources>

<!-- layout -->
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    style="@style/GreenPadded"
    android:theme="@style/BigCenteredText">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Look at me, I'm themed!" />

</FrameLayout>

Android provides some default styles and themes that you can use and extend in your applications:

<resources>
   <!-- Base application theme. -->
   <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
       <!-- Customize your theme here. -->
       <item name="colorPrimary">@color/colorPrimary</item>
       <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
       <item name="colorAccent">@color/colorAccent</item>
   </style>

</resources>

A theme for the whole <application> or an <activity> can be specified in the manifest file:

<manifest ...>
   <application
       android:icon="@mipmap/ic_launcher"
       android:label="Android Manifest"
       android:theme="@style/AppTheme">
       ...
</manifest>

Dimens

Android supports many units of measurement: dp, sp, pt, px, mm, and in.

In the past, developers used pixels when working with computer interfaces. But with the appearance of a wider variety of display densities, this approach became a source of problems. At higher resolutions, elements looked really small. So new units of measurement began to appear that were independent of screen resolution.

Density-independent pixels (dp) are adjusted for screen density to have the same physical size among different devices. Developers use them to specify the sizes of UI elements.

Scalable pixels (sp) are designed for text sizes. They work similarly to dp, but can be scaled by the user in Android Settings. This allows users to change text size without re-scaling the whole user interface.

Both can be used in the <dimen> tag, and the preferred resource file for them is dimens.xml:

<resources>
    <dimen name="font_size">18sp</dimen>
    <dimen name="space">1dp</dimen>
    <dimen name="btn_size">100dp</dimen>
</resources>

You can fetch them using Kotlin code:

val fontSize: Float = resources.getDimension(R.dimen.font_size)
val btnSize: Int = resources.getDimensionPixelSize(R.dimen.btn_size)
val space: Int = resources.getDimensionPixelOffset(R.dimen.space)

The resource system retrieves the dimension and multiplies it by resources.displayMetrics.density for dp, or by resources.displayMetrics.scaledDensity for sp, giving the value in pixels for the current screen density and user's preference.

getDimensionPixelOffset also discards the fractional part to obtain whole pixels. And getDimensionPixelSize rounds the value up, so any non-zero dimension (even 0.0001dp) will be at least 1 pixel.

Unlike many other size-related setters, TextView.setTextSize(float) accepts sp and scales them to pixels on its own. If you already have the size in pixels (like fontSize in the snippet above), use setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize).

In XML, you just need to reference your dimension:

<TextView  
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="@dimen/font_size"/>

Dimension resources are useful when you need to change size according to the current configuration. For example, to specify bigger paddings for landscape orientation in the values-land folder.

Conclusion

The values folder stores files that contain resources of different types. Strings are stored in strings.xml, colors in colors.xml, styles in styles.xml, themes in themes.xml, and element sizes in dimens.xml. Styles and themes help you implement a consistent design system. When sizing elements, remember that you need to use dp and sp.

114 learners liked this piece of theory. 4 didn't like it. What about you?
Report a typo