Maintaining String Resources with Translation in Mind

Ataul is a Google Developer Expert for Android focusing on inclusive design for mobile platforms and loves facilitating the production of universally useable apps. Also, he watches a lot of movies.

Translation and localization is a vital part of any growing app. It is, however, time-consuming—often being carried out in disjointed phases and as such it’s all too often left until the last minute. If you’re not managing your String resources with this fact in mind, you could find yourself with delays in the development (and ultimately the release) of your application.

At Novoda, we’ve slowly converged onto a common approach to managing our String resources that acknowledges this real-world issue and allows us to be flexible with when and how translations are supplied. We’ve found it very helpful for accommodating most translation efforts and have been using it on all projects, even if we don’t believe an application will be translated right now.

The approach itself is fairly simple and consists of 3 rules.

Let’s illustrate this with a concrete example. Here’s a simple Textview label displaying “Hello world” that’s being shown in an Activity named ‘Initial’:

<TextView  
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="@string/initial_welcome_message" />

The @string/initial_welcome_message resource would not be the String literal “Hello world”. Instead, it would be a reference to another resource in a the strings file named after the screen/domain (in this case, res/strings-initial.xml, after our Activity).

<string name="initial_welcome_message">@string/hello_world</string>  

This @string/initial_welcome_message resource then references the @string/hello_world String resource, which is inside the file holding all translated strings. It’s this resource that holds actual text (in this case, “Hello World”) and has literal naming (“hello_world”): res/strings-localised.xml

<string name="hello_world">Hello world</string>  

This layer of indirection allows you to change the referenced resource ID that initial_welcome_message points to as you refactor your code. You therefore wouldn’t need to alter the hello_world String, which it may have been sent for translation. These IDs would remain stable and so prevent conflicts when the translation is completed and the resulting String need to be merged back in.

Once translation has started, the process would be fairly simple:

And that’s it. This approach allows for easy replacement as translated text becomes available without any major refactoring of XML layouts or code, meaning your development process is a lot safer.

I don’t only like it because it makes string translation easier, I like it for the separation of concerns and the use of domain concepts to segregate the string resources into different files, allowing faster development and code maintenance when adding/changing features. Translations is a cheeky bonus, nice!

Paul Blundell

(For a little more detail, and some more concrete examples, here’s a longer description of this process.)

About Novoda

We plan, design, and develop the world’s most desirable Android products. Our team’s expertise helps brands like Sony, Motorola, Tesco, Channel4, BBC, and News Corp build fully customized Android devices or simply make their mobile experiences the best on the market. Since 2008, our full in-house teams work from London, Liverpool, Berlin, Barcelona, and NYC.

Let’s get in contact