In the Files/Static sample project available in the Source Code section of http://apress.com, you will find a reworking of the listbox example from Chapter 8, this time using a static XML file instead of a hard-wired array in Java. The layout is the same:
<?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/selection"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:drawSelectorOnTop="false"
/>
</LinearLayout>
In addition to that XML file, you need an XML file with the words to show in the list:
<words>
<word value="lorem" />
<word value="ipsum" />
<word value="dolor" />
<word value="sit" />
<word value="amet" />
<word value="consectetuer" />
<word value="adipiscing" />
<word value="elit" />
<word value="morbi" />
<word value="vel" />
<word value="ligula" />
<word value="vitae" />
<word value="arcu" />
<word value="aliquet" />
<word value="mollis" />
<word value="etiam" />
<word value="vel" />
<word value="erat" />
<word value="placerat" />
<word value="ante" />
<word value="porttitor" />
<word value="sodales" />
<word value="pellentesque" />
<word value="augue" />
<word value="purus" />
</words>
While this XML structure is not exactly a model of space efficiency, it will suffice for a demo.
The Java code now must read in that XML file, parse out the words, and put them someplace for the list to pick up:
public class StaticFileDemo extends ListActivity {
TextView selection;
ArrayList<String> items = new ArrayList<String>();
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
selection = (TextView)findViewById(R.id.selection);
try {
InputStream in = getResources().openRawResource(R.raw.words);
DocumentBuilder builder = DocumentBuilderFactory
.newInstance().newDocumentBuilder();
Document doc = builder.parse(in, null);
NodeList words = doc.getElementsByTagName("word");
for (int i=0; iwords.getLength(); i++) {
items.add(((Element)words.item(i)).getAttribute("value"));
}
in.close();
} catch (Throwable t) {
Toast
.makeText(this, "Exception: "+t.toString(), 2000).show();
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, items));
}
public void onListItemClick(ListView parent, View v, int position,
long id) {
selection.setText(items.get(position).toString());
}
}
The differences between the Chapter 8 example and this one mostly lie within onCreate(). We get an InputStream for the XML file (getResources().openRawResource(R.raw.words)), then use the built-in XML parsing logic to parse the file into a DOM Document, pick out the word elements, then pour the value attributes into an ArrayList for use by the ArrayAdapter.
The resulting activity looks the same as before (Figure 18-1), since the list of words is the same, just relocated.
Figure 18-1. The StaticFileDemo sample application
Of course, there are even easier ways to have XML files available to you as pre-packaged files, such as by using an XML resource. That is covered in the next chapter. However, while this example uses XML, the file could just as easily have been a simple one-word-per-line list, or in some other format not handled natively by the Android resource system.
Readin’ ’n’ Writin’
Reading and writing your own, application-specific data files is nearly identical to what you might do in a desktop Java application. The key is to use openFileInput() and openFileOutput() on your Activity or other Context to get an InputStream and OutputStream, respectively. From that point forward, the process is not much different from using regular Java I/O logic:
• Wrap those streams as needed, such as using an InputStreamReader or OutputStreamWriter for text-based I/O.
• Read or write the data.
• Use close() to release the stream when done.