Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Xamarin

Displaying Data with an Adapter in Xamarin.Android and Visual Studio

0.00/5 (No votes)
25 Jul 2014CPOL4 min read 44.8K  
Displaying data with an Adapter in Xamarin.Android and Visual Studio

Introduction

For most Xamarin.Android applications you will want to display data of some sort. That may be data from a database, XML or other technology. If you have developed Windows or Web applications using the .NET Framework. then you will be familiar with using UI controls and populating these controls at runtime from data from different sources. Android similarly allows the developer to populate UI controls with data, but there are differences in how you achieve this using Android. The purpose of this article is to show you how you can populate an Android UI control with data using Xamarin.Android and Visual Studio.

Assumptions

For the purposes of this article I will assume the reader is familiar with creating Android screen layouts and implementing classes in C#.

Background

The Adapter class is the bridge between the UI control and the data source. In the world of Android development, all UI controls are collectively referred to as a View. A View is the basic building block for all UI components. The Adapter class returns an instance of a View. When used to display a list of items, the Adapter will return a single View for each data item i.e. a View is returned for each row in the list of items.

The developer is able to manipulate the representation of the data before it is displayed. For example if the data contains a BIT type to represent a True / False condition, the developer can return the words TRUE or FALSE from the View rather than displaying it's raw BIT value.

Very simple Adapter example - A list of items

The following example demonstrates how to display a very simple list of items.

  • Description
  • Make
  • Model
  • Quantity

To keep the article nice and simple I will use XML data to populate the list. Here is a sample of the underlying XML.

XML
<GOODS>
    <GOOD>
        <DESCRIPTION>Description1</DESCRIPTION>
        <MAKE>Item1</MAKE>
        <MODEL>Model1</MODEL>
        <QUANTITY>1</QUANTITY>
    </GOOD>
    <GOOD>
        <DESCRIPTION>Description2</DESCRIPTION>
        <MAKE>Item2</MAKE>
        <MODEL>Model2</MODEL>
        <QUANTITY>2</QUANTITY>
</GOODS>

The data consists of a list of goods. Each goods item has an associated description, make, model and quantity.

Creating the screen

Firstly we will need a screen to display our list of items. Here is a screenshot of how the screen looks in the designer in Visual Studio.

Image 1

Here is the Android XML (AXML) code listing for the ListView element i.e. the View that will actually render the list of goods to the screen.

XML
<ListView
            p1:minWidth="25px"
            p1:minHeight="25px"
            p1:layout_width="match_parent"
            p1:layout_height="match_parent"
            p1:textAppearance="?android:attr/textAppearanceMedium"
            p1:layout_below="@id/textView1"
            p1:id="@+id/GoodsList" />

Here is the complete screen layout (AXML) listing showing the column headings and other UI elements.

XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:p1="http://schemas.android.com/apk/res/android"
    p1:orientation="vertical"
    p1:minWidth="25px"
    p1:minHeight="25px"
    p1:id="@+id/Goods"
    p1:layout_width="fill_parent"
    p1:layout_height="fill_parent">
    <RelativeLayout
        p1:minWidth="25px"
        p1:minHeight="25px"
        p1:layout_width="wrap_content"
        p1:layout_height="fill_parent"
        p1:id="@+id/relativeLayout1"
        p1:padding="5dp"
        p1:layout_weight="0.5">
        <Button
            p1:text="Next"
            p1:layout_width="wrap_content"
            p1:layout_height="wrap_content"
            p1:id="@+id/btnListGoods"
            p1:drawableRight="@android:drawable/ic_media_next"
            p1:layout_alignParentBottom="true"
            p1:layout_alignParentRight="true" />
        <TextView
            p1:text="List of Goods"
            p1:textAppearance="?android:attr/textAppearanceLarge"
            p1:id="@+id/textView1"
            p1:layout_width="wrap_content"
            p1:layout_height="wrap_content" />
        <ListView
            p1:minWidth="25px"
            p1:minHeight="25px"
            p1:layout_width="match_parent"
            p1:layout_height="match_parent"
            p1:textAppearance="?android:attr/textAppearanceMedium"
            p1:layout_below="@id/textView1"
            p1:id="@+id/GoodsList" />
        <TextView
            p1:text="Description"
            p1:textAppearance="?android:attr/textAppearanceSmall"
            p1:layout_width="wrap_content"
            p1:layout_height="wrap_content"
            p1:layout_toRightOf="@id/textView2"
            p1:id="@+id/textView2"
            p1:layout_marginTop="35.2dp" />
        <TextView
            p1:text="Make"
            p1:textAppearance="?android:attr/textAppearanceSmall"
            p1:layout_width="wrap_content"
            p1:layout_height="wrap_content"
            p1:layout_toRightOf="@id/textView2"
            p1:id="@+id/textView3"
            p1:layout_marginTop="35.2dp"
            p1:layout_marginLeft="129.1dp" />
        <TextView
            p1:text="Model"
            p1:textAppearance="?android:attr/textAppearanceSmall"
            p1:layout_width="wrap_content"
            p1:layout_height="wrap_content"
            p1:layout_toRightOf="@id/textView3"
            p1:id="@+id/textView4"
            p1:layout_marginTop="35.2dp"
            p1:layout_marginLeft="167.5dp" />
        <TextView
            p1:text="Serial Numer"
            p1:textAppearance="?android:attr/textAppearanceSmall"
            p1:layout_width="wrap_content"
            p1:layout_height="wrap_content"
            p1:layout_toRightOf="@id/textView4"
            p1:id="@+id/textView5"
            p1:layout_marginTop="35.2dp"
            p1:layout_marginLeft="159.4dp" />
        <TextView
            p1:text="Characteristics"
            p1:textAppearance="?android:attr/textAppearanceSmall"
            p1:layout_width="wrap_content"
            p1:layout_height="wrap_content"
            p1:layout_toRightOf="@id/textView5"
            p1:id="@+id/textView6"
            p1:layout_marginTop="35.2dp"
            p1:layout_marginLeft="116.3dp" />
        <TextView
            p1:text="Quantity"
            p1:textAppearance="?android:attr/textAppearanceSmall"
            p1:layout_width="wrap_content"
            p1:layout_height="wrap_content"
            p1:layout_toRightOf="@id/textView6"
            p1:id="@+id/textView7"
            p1:layout_marginLeft="85.8dp"
            p1:layout_marginTop="35.2dp" />
    </RelativeLayout>
</LinearLayout>

Creating the goods list classes

Next we need to implement the Good and Goods classes as these will form the basis of the article. The Good class represents a single item that will appear in the list. The Goods class represents a list of Good objects i.e. List<Good>

C#
public class Good
{
        public string Description;
        public string Make;
        public string Model;
        public int Quantity = 1;
        
        public Good()
        {

        }
}

public class Goods : List<Good>
{
        public Goods()
        {

        }

	//constructor capable of creating a new list from XML
        public Goods(XElement xRoot)
        {
            if (xRoot == null || !xRoot.HasElements) return;

            var xGoodList = xRoot.Descendants().ToList();

            foreach (Good cg in xGoodList.Select(xGood => new Good(xGood)).Where(cg => !string.IsNullOrEmpty(cg.Description)))
            {
                Add(cg);
            }
        }
}

We now have a screen layout that can display a list of goods and we have class definitions for the Good and Goods classes which will be used to populate the list that is displayed on the screen layout.

Creating the Adapter class

We now need to define an Adapter. As already mentioned, the Adapter is the bridge between the UI View element and the underlying XML data. In this example the Adapter will act as the bridge between our XML data and ListView.

We will derive our Adpater class from the Android BaseAdapter class which is the common base class for all Adapter classes.

C#
using System;
using System.Collections.Generic;
using System.Globalization;

using Android.App;
using Android.Graphics;
using Android.Views;
using Android.Widget;

using Application.Model;

namespace Application.Adapters
{
    public class GoodsAdapter : BaseAdapter<Good>
    {
        private readonly List<Good> _list;
        private readonly Activity _context;

        public GoodsAdapter(Activity context, List<Good> list)
        {
            _context = context;
            _list = list;
        }

        public List<Good> GetList()
        {
            return _list;
        } 

        public override long GetItemId(int position)
        {
            return position;
        }

        public override int Count
        {
            get { return _list.Count; }
        }

        public override Good this[int position]
        {
            get { return _list[position]; }
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            TextView view = new TextView(_context);

            const string space = " ";
            string description = this[position].Description.PadRight(25, Convert.ToChar(space)).Substring(0, 25);
            string make = this[position].Make.PadRight(25, Convert.ToChar(space)).Substring(0, 25);
            string model = this[position].Model.PadRight(25, Convert.ToChar(space)).Substring(0, 25);
            string quantity = this[position].Quantity.ToString(CultureInfo.InvariantCulture).PadRight(5, Convert.ToChar(space)).Substring(0, 5);
            
            //alternate the row colours and set the text foreground / background colours
            var bgColor = position % 2 == 0
                              ? Color.White
                              : Color.LightGray;

            view.SetBackgroundColor(bgColor);
            view.SetTextColor(Color.Black);
            view.SetTypeface(Typeface.Monospace, TypefaceStyle.Bold);
            view.SetHeight(50);

            view.Text = description +
                        make +
                        model +
                        quantity;
            
            return view;
        }

    }
}

Things to note about our Adapter class.

  • The class is derived from BaseAdapter
  • The list of goods and application context are passed in via the constructor and stored as class properties (_list and _context respectively)
  • The GetView() method is the primary method responsible for returning a single View instance for each item in the list i.e. one row in the list is returned by this method

Populate the list of goods

The only remaining step is to populate the Adapter with XML data and diiplay the list of items on the screen. You could add code similar to the following to your Activity or Fragment class to achieve this.

C#
//we will assume xRoot contains a list of goods as per the structure described earlier in the article
Goods _goods = new XElement(xRoot);

var adapter = new GoodsAdapter(Activity, _goods);
var viewGoods = Activity.FindViewById<ListView>(Resource.Id.GoodsList);
viewGoods.Adapter = adapter;

Summary

Hopefully this article has given you sufficient information for you to start creating your own Adapter classes in your Xamarin.Android application. Feel free to leave a comment if you would like me to further elaborate on anything within this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)