Introduction
In this article, we are going to learn about how to create a custom ListView in Xamarin Android app.
Solution
Here are the steps to add tabs in an Android app.
Step 1
Create/ open your Android solution in Visual Studio or Xamarin Studio.
Step 2
Create the ListView inside your AXML file, as shown below.
(File Name: main.axml)
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ListView
- android:id="@+id/listView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:fastScrollEnabled="true" />
- </LinearLayout>
Step 3: Initialize ListView in MainActivity, as shown below.
(File Name: MainActivity.cs)
- public class MainActivity : Activity
- {
-
- ListView myList;
- protected override void OnCreate(Bundle bundle)
- {
- base.OnCreate(bundle);
-
-
- SetContentView(Resource.Layout.Main);
-
- myList = FindViewById<ListView>(Resource.Id.listView);
-
- }
- }
Step 4
Now, create the row for the ListView cell to show the details of the user as Name, Image and Department.
(FileName: userRow.axml)
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:minWidth="25px"
- android:minHeight="25px"
- android:paddingBottom="4dp">
- <ImageView
- android:id="@+id/photoImageView"
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:padding="5dp" />
- <TextView
- android:id="@+id/nameTextView"
- android:layout_toRightOf="@id/photoImageView"
- android:text="Name"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="5dp" />
- <TextView
- android:id="@+id/departmentTextView"
- android:layout_toRightOf="@id/photoImageView"
- android:layout_below="@id/nameTextView"
- android:text="Department"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="5dp" />
- </RelativeLayout>
Step 5
Create User Model, as shown below.
(File Name: User.cs)
- public class User
- {
- public string Name { get; set; }
- public string ImageUrl { get; set; }
- public string Department { get; set; }
- public string Details { get; set; }
-
- public override string ToString()
- {
- return Name + " " + Department;
- }
- }
Step 6
To bind the row, we required ListView Adapter, so create a Custom Adapter, as shown below.
(File Name: MyCustomListAdapter.cs)
- public class MyCustomListAdapter : BaseAdapter<User>
- {
- List<User> users;
-
- public MyCustomListAdapter(List<User> users)
- {
- this.users = users;
- }
-
- public override User this[int position]
- {
- get
- {
- return users[position];
- }
- }
-
- public override int Count
- {
- get
- {
- return users.Count;
- }
- }
-
- public override long GetItemId(int position)
- {
- return position;
- }
-
- public override View GetView(int position, View convertView, ViewGroup parent)
- {
- var view = convertView;
-
- if(view==null)
- {
- view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.userRow, parent, false);
-
- var photo = view.FindViewById<ImageView>(Resource.Id.photoImageView);
- var name = view.FindViewById<TextView>(Resource.Id.nameTextView);
- var department = view.FindViewById<TextView>(Resource.Id.departmentTextView);
-
- view.Tag = new ViewHolder() { Photo = photo, Name = name, Department = department };
- }
-
- var holder = (ViewHolder)view.Tag;
-
- holder.Photo.SetImageDrawable(ImageManager.Get(parent.Context, users[position].ImageUrl));
- holder.Name.Text = users[position].Name;
- holder.Department.Text = users[position].Department;
-
-
- return view;
-
- }
- }
The Custom Adapter is extended by the Base Adapter and it has some Abstract methods, as shown below.
- Count- This method returns the count of the list items.
- GetItemId- It returns the position of the item.
- GetView- This method is used to bind the view to the ListView row, it will bind the data with the row.
Step 7
Now, create the Image Manager class, which is used to bind the images with the ImageView, as shown below.
(File Name: ImageManager.cs)
- public static class ImageManager
- {
- static Dictionary<string, Drawable> cache = new Dictionary<string, Drawable>();
-
- public static Drawable Get(Context context, string url)
- {
- if (!cache.ContainsKey(url))
- {
- var drawable = Drawable.CreateFromStream(context.Assets.Open(url), null);
-
- cache.Add(url, drawable);
- }
-
- return cache[url];
- }
- }
In the code given above, the images are boud with the Assets folder. (Add the images to the Image folder accordingly).
Step 8
Now, we require data source for the list, so we will create UserData file to provide the data to the list, as shown below.
(File Name: UserData.cs)
- public static class UserData
- {
- public static List<User> Users { get; private set; }
-
- static UserData()
- {
- var temp = new List<User>();
-
- AddUser(temp);
- AddUser(temp);
- AddUser(temp);
-
- Users = temp.OrderBy(i => i.Name).ToList();
- }
-
- static void AddUser(List<User> users)
- {
- users.Add(new User()
- {
- Name = "aVirendra Thakur",
- Department = "Xamarin Android & Xamarin Forms Development",
- ImageUrl = "images/image.png",
- Details = "Virendra has over 2 years of experience developing mobile applications,"
- });
-
- users.Add(new User()
- {
- Name = "bVirendra Thakur",
- Department = "Xamarin Android & Xamarin Forms Development",
- ImageUrl = "images/image2.png",
- Details = "Virndra has over 2 years of experience developing mobile applications; specializing in Android & C# cross platform development."
-
- });
- users.Add(new User()
- {
- Name = "bVirendra Thakur",
- Department = "Xamarin Android & Xamarin Forms Development",
- ImageUrl = "images/image.png",
- Details = "Virndra has over 2 years of experience developing mobile applications; specializing in Android & C# cross platform development."
-
- });
-
- users.Add(new User()
- {
- Name = "aVirendra Thakur",
- Department = "Xamarin Android & Xamarin Forms Development",
- ImageUrl = "images/image2.png",
- Details = "Virndra has over 2 years of experience developing mobile applications; specializing in Android & C# cross platform development."
-
- }); users.Add(new User()
- {
- Name = "dVirendra Thakur",
- Department = "Xamarin Android & Xamarin Forms Development",
- ImageUrl = "images/image.png",
- Details = "Virndra has over 2 years of experience developing mobile applications; specializing in Android & C# cross platform development."
-
- });
- }
Step 9
Create ViewHolder Class, which holds the controls of the view. It will only create the controls and reuse it in ListView, which saves the memory.
(File Name: ViewHolder.cs)
- public class ViewHolder: Java.Lang.Object
- {
- public ImageView Photo { get; set; }
- public TextView Name { get; set; }
- public TextView Department { get; set; }
- }
Step 10
Now, go to MyCustomListAdapter and add the few lines of code to bind the data, as shown below.
(File Name: MyCustomListAdapter.cs)
- public override View GetView(int position, View convertView, ViewGroup parent)
- {
- var view = convertView;
-
- if(view==null)
- {
- view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.userRow, parent, false);
-
- var photo = view.FindViewById<ImageView>(Resource.Id.photoImageView);
- var name = view.FindViewById<TextView>(Resource.Id.nameTextView);
- var department = view.FindViewById<TextView>(Resource.Id.departmentTextView);
-
- view.Tag = new ViewHolder() { Photo = photo, Name = name, Department = department };
- }
-
- var holder = (ViewHolder)view.Tag;
-
- holder.Photo.SetImageDrawable(ImageManager.Get(parent.Context, users[position].ImageUrl));
- holder.Name.Text = users[position].Name;
- holder.Department.Text = users[position].Department;
-
-
- return view;
-
- }
Step 11
Add the Custom Adapter to the ListView in MainActivity, as shown below.
- protected override void OnCreate(Bundle bundle)
- {
- base.OnCreate(bundle);
-
-
- SetContentView(Resource.Layout.Main);
-
- myList = FindViewById<ListView>(Resource.Id.listView);
-
- myList.Adapter = new MyCustomListAdapter(UserData.Users);
- }
Output
Now, run the Application and you will see the output given below.