Custom List View using ArrayList

It's a common practice in Android applications to display a list of elements in your Android application.  For the most part you will be displaying this list from your database using a database cursor.  If your data comes from a different source like a web service, data feed or data file, you will need to create a custom view adapter for your ListView.

In a traditional list activity your application will have a layout and an activity class.  To display a custom list view you will need to create a new layout that will represent just one row in the list and a custom ArrayAdapter to map your view layout to your data model.  I've provided code snippets of all of these from my golf application.

First thing you will want to define is the layout of your data.  This custom layout will be used in the main layout of your application to represent the rows of data.  In a custom list view you know you will be working with a collection of objects.  You need to define which elements of the data model you will want to display in each row.  In the code example below I'm defining four data elements: course, teeBox, par and holes.  I will specify these components in the custom ArrayAdapter class I create later.

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
  android:layout_width="fill_parent"
  android:layout_height="50dip"
  android:stretchColumns="*">
  <TableRow>
      <TextView
        android:id="@+id/course_item"
        android:layout_width="140dip"
        android:layout_height="wrap_content"
        style="@style/ListsText"
        android:textColor="@color/title_text"/>
      <TextView
        android:id="@+id/teeBox_item"
        android:layout_width="80dip"
        android:layout_height="wrap_content"
        style="@style/ListsText"
        android:textColor="@color/title_text"/>
      <TextView
        android:id="@+id/par_item"
        android:layout_width="50dip"
        android:layout_height="wrap_content"
        style="@style/ListsText"
        android:textColor="@color/title_text"/>
      <TextView
        android:id="@+id/holes_item"
        android:layout_width="50dip"
        android:layout_height="wrap_content"
        style="@style/ListsText"
        android:textColor="@color/title_text"/>
    </TableRow>
</TableLayout>

In your main activity class for the list screen you will need to define ListView, retrieve the list data and specify a new  Adapter to display the data. The code below shows all of this in one block.  We define a new ListView based on the courseListView layout and we use the courseService to retrieve a java.util.List of Course objects.  Finally we create a new ListAdapter using a custom adapter that specified the detail item's layout and the collection.  The adapter is then set on the ListView to link it to the main layout.

ListView courseListView = (ListView) findViewById(R.id.courseListView);
 
List<Course> courses = courseService.findAll();
         
final ListAdapter adapter = new CourseAdaptor(this, R.layout.course_item, courses);
courseListView.setAdapter(adapter);

The key component to the code above is the custom AttayAdapter.  To display the data in the list exactly the way you want it to look, you need to create a custom adapter for the data model.  For this example we will create a constructor that takes a context, resource id and an array of objects.  

The getView method needs to be overridden to return a new view that will represent a row of data.  In the getView method, we will get references to the TextViews defined in the custom layout we defined earlier.  Since we know the row id or position we are in the list, we get the associated row from the collection and map that data to the view.  Below is an example of that code.

public class CourseAdaptor extends ArrayAdapter<Course> {
    private int resource;
     
    public CourseAdaptor(Context context, int resource, List<Course> objects) {
        super(context, resource, objects);
        this.resource = resource;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LinearLayout layout;
         
        Course course = getItem(position);
        String name = course.getName();
        String teebox = course.getTeeBox();
        String par = course.getPar()+"";
        String holes = course.getHoles()+"";
         
        if (convertView == null) {
            layout = new LinearLayout(getContext());
            String inflater = Context.LAYOUT_INFLATER_SERVICE;
            LayoutInflater vi = (LayoutInflater)getContext().getSystemService(inflater);
            vi.inflate(resource, layout, true);
        } else {
            layout = (LinearLayout)convertView;
        }
         
        TextView nameView = (TextView)layout.findViewById(R.id.course_item);
        TextView teeboxView = (TextView)layout.findViewById(R.id.teeBox_item);
        TextView parView = (TextView)layout.findViewById(R.id.par_item);
        TextView holesView = (TextView)layout.findViewById(R.id.holes_item);
         
        nameView.setText(name);
        teeboxView.setText(teebox);
        parView.setText(par);
        holesView.setText(holes);
         
        return layout;
    }
}


Finally all we need to do is include the ListView in our main layout.  This is a fairly simple component to add to your main layout since all the details are defined in the included layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical">
    <ListView
    android:id="@+id/courseListView" 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:cacheColorHint="@color/background2"
    />
</LinearLayout>


I hope this use case was clear enough for people to understand.  In the long run this is probably a very common pattern in Android and a very simple one to execute.  The use case does require an Activity class, an implementation of ArrayAdapter and a pair of layout xml files but most of the hard stuff is abstracted away for you.  Please comment or email me if you have any questions.

 

What did you think of this article?




Trackbacks
  • Trackbacks are closed for this post.
Comments
  • No comments exist for this post.
Leave a comment

 Name (required)

 Email (will not be published) (required)

Your comment is 0 characters limited to 3000 characters.