Building a Mobile Employee Directory – Step 2: Load data into the ListActivity from an XML file via XmlParser
For the source code relating to this post, checkout this Github repository.
Parsing XML data with XmlPullParser into an Android ListView.
After reviewing the SAX (Simple API for XML) Parser, the DOM (Document Object Model) Parser and the XmlPullParser. I’ve decided to use the XmlPullParser because it is supposed to be the fastest. I have not tried the JDOM Parser.
employee_list.xml (in res/xml)
<?xml version="1.0" encoding="utf-8"?> <employees> <employee> <id>1</id> <firstName>John</firstName> <lastName>Doe</lastName> <title>CEO</title> <city>San Francisco, CA</city> <managerId>0</managerId> <department>Corporate</department> <officePhone>123-456-0001</officePhone> <mobilePhone>987-654-1234</mobilePhone> <email>John@mail.com</email> <picture>placeholder.jpg</picture> </employee> <employee> <id>2</id> <firstName>Barack</firstName> <lastName>Obama</lastName> <title>President</title> <city>Washington DC</city> <department>Corporate</department> <managerId>0</managerId> <officePhone>123-456-0002</officePhone> <mobilePhone>781-000-0002</mobilePhone> <email>Barack@mail.com</email> <picture>barack_obama.jpg</picture> </employee> <employee> <id>3</id> <firstName>Joe</firstName> <lastName>Biden</lastName> <title>VP</title> <city>Washington DC</city> <managerId>2</managerId> <department>Corporate</department> <officePhone>123-456-0003</officePhone> <mobilePhone>987-654-1234</mobilePhone> <email>Joe@mail.com</email> <picture>joe_biden.jpg</picture> </employee> <employee> <id>4</id> <firstName>Hillary</firstName> <lastName>Clinton</lastName> <title>Secretary of State</title> <city>Washington DC</city> <managerId>2</managerId> <department>Corporate</department> <officePhone>123-456-0004</officePhone> <mobilePhone>987-654-1234</mobilePhone> <email>Hillary@mail.com</email> <picture>hillary_clinton.jpg</picture> </employee> </employees>
EmployeeXmlParser.java
package com.himebaugh.employeedirectory; import java.io.IOException; import java.util.ArrayList; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; public class EmployeeXmlParser { // names of the XML tags static final String EMPLOYEES = "employees"; static final String EMPLOYEE = "employee"; static final String ID = "id"; static final String FIRSTNAME = "firstName"; static final String LASTNAME = "lastName"; static final String TITLE = "title"; static final String DEPARTMENT = "department"; static final String CITY = "city"; static final String OFFICEPHONE = "officePhone"; static final String MOBILEPHONE = "mobilePhone"; static final String EMAIL = "email"; static final String PICTURE = "picture"; ArrayList<Employee> employeeList = null; private Employee currentEmployee = null; private boolean done = false; private String currentTag = null; public ArrayList<Employee> parse(Context context) { XmlPullParser parser = context.getResources().getXml(R.xml.employee_list); try { int eventType = parser.getEventType(); // Following logic modified from http://www.ibm.com/developerworks/library/x-android/ // Also look at http://developer.android.com/training/basics/network-ops/xml.html while (eventType != XmlPullParser.END_DOCUMENT && !done) { switch (eventType) { case XmlPullParser.START_DOCUMENT: employeeList = new ArrayList<Employee>(); break; case XmlPullParser.START_TAG: currentTag = parser.getName(); if (currentTag.equalsIgnoreCase(EMPLOYEE)) { currentEmployee = new Employee(); } else if (currentEmployee != null) { if (currentTag.equalsIgnoreCase(ID)) { currentEmployee.setId(Integer.parseInt(parser.nextText())); // currentEmployee.setId(parser.nextText()); } else if (currentTag.equalsIgnoreCase(FIRSTNAME)) { currentEmployee.setFirstName(parser.nextText()); } else if (currentTag.equalsIgnoreCase(LASTNAME)) { currentEmployee.setLastName(parser.nextText()); } else if (currentTag.equalsIgnoreCase(TITLE)) { currentEmployee.setTitle(parser.nextText()); } else if (currentTag.equalsIgnoreCase(DEPARTMENT)) { currentEmployee.setDepartment(parser.nextText()); } else if (currentTag.equalsIgnoreCase(CITY)) { currentEmployee.setCity(parser.nextText()); } else if (currentTag.equalsIgnoreCase(OFFICEPHONE)) { currentEmployee.setOfficePhone(parser.nextText()); } else if (currentTag.equalsIgnoreCase(MOBILEPHONE)) { currentEmployee.setMobilePhone(parser.nextText()); } else if (currentTag.equalsIgnoreCase(EMAIL)) { currentEmployee.setEmail(parser.nextText()); } else if (currentTag.equalsIgnoreCase(PICTURE)) { currentEmployee.setPicture(parser.nextText()); } } break; case XmlPullParser.END_TAG: currentTag = parser.getName(); if (currentTag.equalsIgnoreCase(EMPLOYEE) && currentEmployee != null) { employeeList.add(currentEmployee); } else if (currentTag.equalsIgnoreCase(EMPLOYEES)) { done = true; } break; } eventType = parser.next(); } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return employeeList; } }
MainActivity.java
package com.himebaugh.employeedirectory; import java.util.List; import android.app.ListActivity; import android.os.AsyncTask; import android.os.Bundle; import android.view.Menu; import android.widget.ArrayAdapter; // GOAL: Build a native android Mobile Employee Directory // ** The result is similar to the sample with Flex and Flash Builder // see http://www.adobe.com/devnet/flex/articles/employee-directory-android-flex.html // PURPOSE: Learning how to build an Android App. // Step 2: Load data into the ListActivity from an XML file via XmlParser // 1) employee_list.xml (in res/xml) // 2) Employee.java // 3) EmployeeXmlParser.java public class MainActivity extends ListActivity { public List<Employee> employees = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * This will work, but best practice is to place in a non-ui thread like below. * * EmployeeXmlParser parser = new EmployeeXmlParser(); * employees = parser.parse(this); * * ArrayAdapter<Employee> adapter = new ArrayAdapter<Employee>(this, android.R.layout.simple_list_item_1, employees); * setListAdapter(adapter); */ // Parse xml data in a non-ui thread new LoadEmployeesTask().execute(); } private class LoadEmployeesTask extends AsyncTask<String, Void, List<Employee>> { @Override protected List<Employee> doInBackground(String... args) { // CALL XMLPULLPARSER & RETURN A LIST EmployeeXmlParser parser = new EmployeeXmlParser(); employees = parser.parse(getBaseContext()); return employees; } @Override protected void onPostExecute(List<Employee> employees) { ArrayAdapter<Employee> adapter = new ArrayAdapter<Employee>(getBaseContext(), android.R.layout.simple_list_item_1, employees); setListAdapter(adapter); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
Employee.java
package com.himebaugh.employeedirectory; public class Employee { Integer _empID; String _firstName; String _lastName; String _title; String _department; String _city; String _officePhone; String _mobilePhone; String _email; String _picture; // constructor public Employee() { } // constructor with parameters public Employee(Integer empID, String firstName, String lastName, String title, String department, String city, String officePhone, String mobilePhone, String email, String picture) { this._empID = empID; this._firstName = firstName; this._lastName = lastName; this._title = title; this._department = department; this._city = city; this._officePhone = officePhone; this._mobilePhone = mobilePhone; this._email = email; this._picture = picture; } // All set methods public void setId(Integer empID) { this._empID = empID; } public void setFirstName(String firstName) { this._firstName = firstName; } public void setLastName(String lastName) { this._lastName = lastName; } public void setTitle(String title) { this._title = title; } public void setDepartment(String department) { this._department = department; } public void setCity(String city) { this._city = city; } public void setOfficePhone(String officePhone) { this._officePhone = officePhone; } public void setMobilePhone(String mobilePhone) { this._mobilePhone = mobilePhone; } public void setEmail(String email) { this._email = email; } public void setPicture(String picture) { this._picture = picture; } // All get methods public Integer getId() { return this._empID; } public String getFirstName() { return this._firstName; } public String getLastName() { return this._lastName; } public String getTitle() { return this._title; } public String getDepartment() { return this._department; } public String getCity() { return this._city; } public String getOfficePhone() { return this._officePhone; } public String getMobilePhone() { return this._mobilePhone; } public String getPicture() { return this._picture; } // @Override public String toString() { return _firstName + " " + _lastName + "\n" + _title; } }
activity_main.xml (in res/layout)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > </ListView> </RelativeLayout>
Screenshot of the application
Category: Android Application Development
Thank you. Nice explanation.
how do i open a single list item from your list,such that when a user clicks on one list item it displays the contents of that specific list item
The code has been place on GitHub. Download at https://github.com/langhimebaugh/EmployeeDirectory/tree/Step-2