Android allows you to define multiple strings in one or more XML resource files. These XML files containing string-resource definitions reside in the /res/values subdirectory. The names of the XML files are arbitrary, although you will commonly see the file name as strings.xml. Listing 3–1 shows an example of a string-resource file.
Listing 3–1. Example strings.xml File
<?xml version="1.0" encoding="utf-8"?> <resources>
<string name="hello">hello</string>
<string name="app_name">hello appname</string> </resources>
When this file is created or updated, the Eclipse ADT plug-in will automatically create or update a Java class in your application’s root package called R.java with unique IDs for the two string resources specified.
Notice the placement of this R.java file below. We have given a high level directory structure for a project like, say, “MyProject.”
\MyProject \src \com\mycompany\android\my-root-package \com\mycompany\android\my-root-package\another-package \gen \com\mycompany\android\my-root-package\ \com\mycompany\android\my-root-package\R.java \assets \res \AndroidManifest.xml …..etc
NOTE: Regardless of the number of resource files, there is only one R.java file.
For the string-resource file in Listing 3–1, the updated R.java file would have these entries:
package com.mycompany.android.my-root-package; public final class R {
...other entries depending on your project and application
public static final class string {
...other entries depending on your project and application
public static final int hello=0x7f040000; public static final int app_name=0x7f040001;
...other entries depending on your project and application }
...other entries depending on your project and application }
Notice, first, how R.java defines a top level class in the root package: public static final class R. Within that outer class of R, Android defines an inner class, namely, static final class string. R.java creates this inner static class as a namespace to
hold string-resource IDs.
The two static final ints defined with variable names hello and app_name are the
resource IDs that represent the corresponding string resources. You could use these resource IDs anywhere in the source code through the following code structure:
R.string.hello
Note that these generated IDs point to ints rather than strings. Most methods that take
strings also take these resource identifiers as inputs. Android will resolve those ints to strings where needed.
It is merely a convention that most sample applications define all strings in one
strings.xml file. Android takes any number of arbitrary files as long as the structure of
the XML file looks like Listing 3–1 and the file resides in the /res/values subdirectory.
The structure of this file is easy to follow. You have the root node of <resources>
followed by one or more of its child elements of <string>. Each <string> element or
node has a property called name that will end up as the id attribute in R.java.
To see that multiple string-resource files are allowed in this subdirectory, you can place another file with the following content in the same subdirectory and call it strings1.xml: <?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello1">hello 1</string>
<string name="app_name1">hello appname 1</string> </resources>
The Eclipse ADT plug-in will validate the uniqueness of these IDs at compile time and place them in R.java as two additional constants: R.string.hello1 and
R.string.app_name1.
Layout Resources
In Android, the view for a screen is often loaded from an XML file as a resource. These XML files are called layout resources. A layout resource is an essential key resource used in Android UI programming. Consider this code segment for a sample Android activity:
public class HelloWorldActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.main);
TextView tv = (TextView)this.findViewById(R.id.text1); tv.setText("Try this text instead");
……… }
The line setContentView(R.layout.main) points out that there is a static class called R.layout, and within that class there is a constant called main (an integer) pointing to a View defined by an XML layout-resource file. The name of the XML file would be main.xml, which needs to be placed in the resources’ layout subdirectory. In other words, this statement would expect the programmer to create the file
/res/layout/main.xml and place the necessary layout definition in that file. The contents of the main.xml layout file could look like Listing 3–2.
Listing 3–2. Example main.xml Layout File <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/text1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/b1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@+string/hello" /> </LinearLayout>
The layout file in Listing 3–2 defines a root node called LinearLayout, which contains a TextView followed by a Button. A LinearLayout lays out its children vertically or horizontally—vertically, in this example.
You will need to define a separate layout file for each screen. More accurately, each layout needs a dedicated file. If you are painting two screens, you will likely need two layout files such as /res/layout/screen1_layout.xml and
/res/layout/screen2_layout.xml.
NOTE: Each file in the /res/layout/ subdirectory generates a unique constant based on the name of the file (extension excluded). With layouts, what matters is the number of files; with string resources, what matters is the number of individual string resources inside the files.
For example, if you have two files under /res/layout/ called file1.xml and file2.xml, you’ll have the following entries in R.java:
public static final class layout { .... any other files
public static final int file1=0x7f030000; public static final int file2=0x7f030001; }
The views defined in these layout files such as a TextView (see Listing 3–2) are
accessible in Java code through their resource IDs generated in R.java: TextView tv = (TextView)this.findViewById(R.id.text1);
tv.setText("Try this text instead");
In this example, you locate the TextView by using the findViewById method of the Activity class. The constant R.id.text1 corresponds to the ID defined for the TextView.
The id for the TextView in the layout file is as follows: <TextView android:id="@+id/text1"
..
</TextView>
The attribute value for the id attribute indicates that a constant called text1 will be used
to uniquely identify this view among other views hosted by that activity. The plus sign (+)
in @+id/text1 means that the ID text1 will be created if it doesn’t exist already. There is
more to this resource ID syntax. We’ll talk about that next.