ListView to show Contact View in Android xamarin

This article demonstrates about how to display the data in ListView, bind the image as list item and highlight the current section alphabet while scrolling. This feature is beeing explained in plain Android Xamarin and MVVMCross.

Android includes the built in ListActivity class which creates ListView and exposes a List Adapter to display the row views.
Follow below steps to implement the features as described above.

1) Create a class “HomeScreen.cs”, inherits from ListActivity .

public class HomeScreen : ListActivity {}

2) Prepare the data to be displayed in ListView. Here, I have created the data and reading from txt file.

List<string> veges = new List<string>();
            Stream seedDataStream = Assets.Open(@"VegeData.txt");
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
             using (StreamReader reader = new StreamReader(seedDataStream)) {
                 while (!reader.EndOfStream) {
                     veges.Add(reader.ReadLine());
                }
            }
4) For displaying the data in ascending order, sort the List object as below.

veges.Sort((x, y) => { return x.CompareTo(y); });

5) For customizing the behaviour of ListView to control what data to be displayed, create a item template which will be shows as ListView item and Adapter. Here I am customizing the ListView to display image and Name, hence created the template as below.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     
android:layout_width="fill_parent"
    
android:layout_height="fill_parent">
    <ImageView
        
android:id="@+id/ContactImage"
        
android:layout_width="50dp"
        
android:layout_height="50dp"
        
android:layout_margin="5dp" />
    <TextView
        
android:id="@+id/ContactName"
        
android:layout_width="wrap_content"
        
android:layout_height="wrap_content"
        
android:textAppearance="?android:attr/textAppearanceLarge"
         
android:layout_marginLeft="5dp" />
</LinearLayout>

6) Create the Adapter by inheriting the BaseAdapter. If you inherit from base adapter you should override the following methods.
Count – To tell the control how many rows are in the data.
GetView – To return a View for each row, populated with data. This method has a parameter for the ListView to pass in an existing, unused row for re-use.
GetItemId – Return a row identifier (typically the row number, although it can be any long value that you like).
this[int] indexer – To return the data associated with a particular row number.

7) The implementation of four methods as follows.

public class HomeScreenAdapter : BaseAdapter<string> {
   string[] items;
   Activity context;
   public HomeScreenAdapter(Activity context, string[] items) : base() {
       this.context = context;
       this.items = items;
   }
   public override long GetItemId(int position)
  {
       return position;
   }
   public override string this[int position] {  
       get { return items[position]; }
   }
   public override int Count {
       get { return items.Length; }
   }
public override View GetView(int position, View convertView, ViewGroup parent)
        {
            var view = convertView ?? context.LayoutInflater.Inflate(Resource.Layout.list_item, parent, false);
            var contactName = view.FindViewById<TextView>(Resource.Id.ContactName);
            var contactImage = view.FindViewById<ImageView>(Resource.Id.ContactImage);
            contactName.Text = items[position];
             contactImage.SetImageResource(Resource.Drawable.Icon);
            return view;
        }

From above GetView function, getting the list item template, its controls and setting the text and image values.

8) Inherit the adapter class from ISectionIndexer interface to supply the index text depending on the rows being displayed.
9) To implement ISectionIndexer you need to add three methods to an adapter:
GetSections – Provides the complete list of section index titles that could be displayed. This method requires an array of Java Objects so the code needs to create a Java.Lang.Object[] from a .NET collection. In our example it returns a list of the initial characters in the list as Java.Lang.String .
GetPositionForSection – Returns the first row position for a given section index.
GetSectionForPosition – Returns the section index to be displayed for a given row.

10) Add below piece of code in constructor for preparing the index text.

alphaIndex = new Dictionary<string, int>();
             for (int i = 0; i < items.Length; i++)
            {
                var key = items[i][0].ToString();
                 if (!alphaIndex.ContainsKey(key))
                     alphaIndex.Add(key, i);
            }
            sections = new string[alphaIndex.Keys.Count];
            alphaIndex.Keys.CopyTo(sections, 0);
            sectionsObjects = new Java.Lang.Object[sections.Length];
             for (int i = 0; i < sections.Length; i++)
            {
                sectionsObjects[i] = new Java.Lang.String(sections[i]);
            }

11) Implement the ISectionIndexer methods as below.

public
int GetPositionForSection(int section)
        {
           return alphaIndex[sections[section]];
      }
public Java.Lang.Object[] GetSections()
         {
             return sectionsObjects;
        }

12) Enable the fast scrolling for ListView.

ListView.FastScrollEnabled = true;

13) Complete OnCrete function of activity with custom adapter as follows.

protected
override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

           List<string> veges = new List<string>();
            Stream seedDataStream = Assets.Open(@"VegeData.txt");
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
             using (StreamReader reader = new StreamReader(seedDataStream)) {
                 while (!reader.EndOfStream) {
                     veges.Add(reader.ReadLine());
                }
            }
            veges.Sort((x, y) => { return x.CompareTo(y); });
            items = veges.ToArray();

            ListAdapter = new HomeScreenAdapter(this, items);

            ListView.FastScrollEnabled = true;
        }

If you are using MVVMCross design pattern, the implementaion is almost similar. But use MVX componenets.

Download the working sample from below location
Plain Android xamarin
http://nullskull.com/FileUpload/-407123783_ListViewWithSectionIndex.zip      

MVVMCross
http://nullskull.com/FileUpload/-407123783_ContactsSample.zip      

By Siva Jagan Dhulipalla   Popularity  (2591 Views)