Forum Xamarin.Android

how to make a custom expandable list view?

JunCainJunCain Member ✭✭✭
edited March 2019 in Xamarin.Android

This is a sms app, and I want to make an expandable list view for my sent items or sent sms, I want to make the recipeint number as a header of my expandable list view.

MyExpandableListview.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Java.Lang;
using MhylesApp.ViewHolder;

namespace MhylesApp.CustomAdapter
{
    public class ExistingCustExpandableAdapter : BaseExpandableListAdapter
    {
        private Context context;
        private List<string> _listGroup;
        private Dictionary<string, List<string>> _lastChild;

        public ExistingCustExpandableAdapter(Context context, List<string> _listGroup, Dictionary<string, List<string>> _lastChild)
        {
            this.context = context;
            this._listGroup = _listGroup;
            this._lastChild = _lastChild;
        }
        public override int GroupCount
        {
            get
            {
                return _listGroup.Count;
            }
        }
        public override bool HasStableIds
        {
            get
            {
                return false;
            }
        }

        public override Java.Lang.Object GetChild(int groupPosition, int childPosition)
        {
            var result = new List<string>();
            _lastChild.TryGetValue(_listGroup[groupPosition], out result);
            return result[childPosition];
        }

        public override long GetChildId(int groupPosition, int childPosition)
        {
            return childPosition;
        }

        public override int GetChildrenCount(int groupPosition)
        {
            var result = new List<string>();
            _lastChild.TryGetValue(_listGroup[groupPosition], out result);
            return result.Count;
        }

        public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
        {
            if(convertView == null)
            {
                LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
                convertView = inflater.Inflate(Resource.Layout.mySmsItems, null);
                TextView phoneNum = convertView.FindViewById<TextView>(Resource.Id.phoneNum);
                TextView agentName = convertView.FindViewById<TextView>(Resource.Id.agentName);
                TextView custName = convertView.FindViewById<TextView>(Resource.Id.custName);
                TextView products = convertView.FindViewById<TextView>(Resource.Id.products);
                TextView sendDate = convertView.FindViewById<TextView>(Resource.Id.sendDate);
                TextView myResult = convertView.FindViewById<TextView>(Resource.Id.myReslt);

                convertView.Tag = new ExistingCustSentOrderViewHolder()
                {
                    phoneNum = phoneNum,
                    agentName = agentName,
                    custName = custName,
                    products = products,
                    sendDate = sendDate,
                    sentResult = myResult,
                };
            }
            var holder = (ExistingCustSentOrderViewHolder)convertView.Tag;
            //TextView phoneNum = convertView.FindViewById<TextView>(Resource.Id.phoneNum);
            //TextView agentName = convertView.FindViewById<TextView>(Resource.Id.agentName);
            //TextView custName = convertView.FindViewById<TextView>(Resource.Id.custName);
            //TextView products = convertView.FindViewById<TextView>(Resource.Id.products);
            //TextView sendDate = convertView.FindViewById<TextView>(Resource.Id.sendDate);
            //TextView myResult = convertView.FindViewById<TextView>(Resource.Id.myReslt);
            string content = (string)GetChild(groupPosition, childPosition);
            holder.phoneNum.Text = content;
            holder.agentName.Text = content;
            holder.custName.Text = content;
            holder.products.Text = content;
            holder.sendDate.Text = content;
            holder.sentResult.Text = content;
            return convertView;

        }

        public override Java.Lang.Object GetGroup(int groupPosition)
        {
            return _listGroup[groupPosition];
        }

        public override long GetGroupId(int groupPosition)
        {
            return groupPosition;
        }

        public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
        {
            if(convertView == null)
            {
                LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
                convertView = inflater.Inflate(Resource.Layout.ExpandableHeader, null);
                TextView SentItemGroup = convertView.FindViewById<TextView>(Resource.Id.SentItemGroup);

                convertView.Tag = new ExistingCustSentOrderViewHolder()
                {
                    phoneNum = SentItemGroup
                };
            }
            string sentItemGroup = (string)GetGroup(groupPosition);
            var holder = (ExistingCustSentOrderViewHolder)convertView.Tag;
            holder.phoneNum.Text = sentItemGroup;
            return convertView;
        }

        public override bool IsChildSelectable(int groupPosition, int childPosition)
        {
            return true;
        }
    }
}

myTextViewHolder.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace MhylesApp.ViewHolder
{
    public class ExistingCustSentOrderViewHolder : Java.Lang.Object
    {
        public TextView phoneNum { get; set; }
        public TextView agentName { get; set; }
        public TextView custName { get; set; }
        public TextView products { get; set; }
        public TextView sendDate { get; set; }
        public TextView sentResult { get; set; }
    }
}

MainActivity.cs
Adding data.

          public static List<ExistingCustSentOrders> existingCustSentOrders = new List<ExistingCustSentOrders>();
                private static void insertIntoExistingCustOrderSentList()
                {
                    ExistingCustSentOrders _orderSent = new ExistingCustSentOrders()
                    {
                        phoneNum = _recipient,
                        agentName = "Agent Name: " + _agentName,
                        custName = "Customer Name: " +_custName,
                        products = string.Join("\n", sentProducts),
                        sendDate = txtdate.Text,
                        sentResult = myResult + ":",
                    };
                    existingCustSentOrders.OrderBy(i => i.sendDate).ToList();
                    existingCustSentOrders.Add(_orderSent);
             }

SentItems.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace MhylesApp.Model
{
    public class ExistingCustSentOrders
    {
        public string phoneNum { get; set; }
        public string agentName { get; set; }
        public string custName { get; set; }
        public string products { get; set; }
        public string sendDate { get; set; }
        public string sentResult { get; set; }
    }
}

MainActivity.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">

    <ExpandableListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/ExpandedSentItem"/>

</LinearLayout>

ExpandableHeader.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/SentItemGroup"
        android:layout_width="wrap_content"
        android:textSize="16sp"
        android:layout_height="wrap_content"/>

</LinearLayout>
Tagged:

Answers

  • JunCainJunCain Member ✭✭✭

    mySmsItems.axml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:id="@+id/phoneNum"
            android:layout_width="match_parent"
            android:textColor="#ffffff"
            android:padding="5dp"
            android:layout_height="wrap_content"
            android:justificationMode="inter_word"
            android:gravity="center_horizontal"/>
        <TextView
            android:id="@+id/agentName"
            android:layout_width="match_parent"
            android:textColor="#ffffff"
            android:padding="5dp"
            android:layout_height="wrap_content"
            android:justificationMode="inter_word"
            android:layout_below="@id/phoneNum"/>
        <TextView
            android:id="@+id/custName"
            android:layout_width="match_parent"
            android:textColor="#ffffff"
            android:padding="5dp"
            android:layout_height="wrap_content"
            android:justificationMode="inter_word"
            android:layout_below="@id/agentName"/>
        <TextView
            android:id="@+id/orderProdHeader"
            android:layout_width="match_parent"
            android:textColor="#ffffff"
            android:padding="5dp"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:text="Ordered Products"
            android:layout_below="@id/custName"/>
        <TextView
            android:id="@+id/products"
            android:layout_below="@id/orderProdHeader"
            android:justificationMode="inter_word"
            android:textColor="#ffffff"
            android:padding="5dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/sendDate"
            android:layout_width="wrap_content"
            android:textColor="#ffffff"
            android:padding="5dp"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:textStyle="italic"
            android:layout_below="@id/products"/>
        <TextView
            android:id="@+id/myReslt"
            android:layout_toLeftOf="@id/sendDate"
            android:layout_alignTop="@id/sendDate"
            android:layout_width="wrap_content"
            android:textColor="#ffffff"
            android:padding="5dp"
            android:layout_height="wrap_content"
            android:textStyle="italic"/>
    
    </RelativeLayout>
    
  • JarvanJarvan Member, Xamarin Team Xamurai
    edited April 2019

    I've reproduced the issue and it works fine. You need to create a group_layout for listGroup and a child_layout for listChild as the following
    code shows.
    ExistingCustExpandableAdapter.cs

    public class ExistingCustExpandableAdapter : BaseExpandableListAdapter
    {
        private Context context;
        private List<string> _listGroup;
        private Dictionary<string, List<string>> _listChild;
    
    
        public ExistingCustExpandableAdapter(Context context, List<string> _listGroup, Dictionary<string, List<string>> _listChild)
        {
            this.context = context;
            this._listGroup = _listGroup;
            this._listChild = _listChild;
        }
        public override int GroupCount
        {
            get
            {
                return _listGroup.Count;
            }
        }
        public override bool HasStableIds
        {
            get
            {
                return true;
            }
        }
    
        public override Java.Lang.Object GetChild(int groupPosition, int childPosition)
        {
            return _listChild[_listGroup[groupPosition]][childPosition];
        }
        public override long GetChildId(int groupPosition, int childPosition)
        {
            return childPosition;
        }
    
        public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
        {
            string childText = (string)GetChild(groupPosition, childPosition);
            if (convertView == null)
            {
                convertView = LayoutInflater.From(context).Inflate(Resource.Layout.expandable_child, null);
            }
            TextView txtListChild = (TextView)convertView.FindViewById(Resource.Id.expandablechild_list);
            txtListChild.Text = childText;
            return convertView;
        }
    
        public override int GetChildrenCount(int groupPosition)
        {
            return _listChild[_listGroup[groupPosition]].Count;
        }
        public override Java.Lang.Object GetGroup(int groupPosition)
        {
            return _listGroup[groupPosition];
        }
    
        public override long GetGroupId(int groupPosition)
        {
            return groupPosition;
        }
    
        public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
        {
            string headerTitle = (string)GetGroup(groupPosition);
            convertView = LayoutInflater.From(context).Inflate(Resource.Layout.expandable_group, null);
            var lblListHeader = (TextView)convertView.FindViewById(Resource.Id.expandablegroup_list);
            lblListHeader.Text = headerTitle;
    
            return convertView;
        }
    
        public override bool IsChildSelectable(int groupPosition, int childPosition)
        {
            return true;
        }
    }
    

    expandable_child.axml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp"
        android:background="#fff69212">
        <TextView
            android:id="@+id/expandablechild_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#ffffffff"
            android:layout_gravity="center_vertical"
            android:paddingLeft="20dp"
            android:textSize="20sp"/>
    </LinearLayout>
    

    expandable_group.axml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp"
        android:background="#fff69212">
        <TextView
            android:id="@+id/expandablegroup_list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#ffffffff"
            android:layout_gravity="center_vertical"
            android:paddingLeft="20dp"
            android:textSize="20sp"/>
    </LinearLayout>
    

    MainActivity.cs

    public class MainActivity : AppCompatActivity
    {
        ExistingCustExpandableAdapter listAdapter;
        ExpandableListView expListView;
        List<string> _listGroup;
        Dictionary<string, List<string>> _listChild;
    
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            // Set our view from the "main" layout resource
            //SetContentView(Resource.Layout.activity_main);
            SetContentView(Resource.Layout.layout1);
            expListView = FindViewById<ExpandableListView>(Resource.Id.expand_listview);
            FnGetListData();
    
            listAdapter = new ExistingCustExpandableAdapter(this, _listGroup, _listChild);
    
            expListView.SetAdapter(listAdapter);
        }
    
        void FnGetListData()
        {
            _listGroup = new List<string>();
            _listChild = new Dictionary<string, List<string>>();
    
            // Adding group data
            _listGroup.Add("Computer science");
            _listGroup.Add("Electrocs & comm.");
            _listGroup.Add("Mechanical");
    
            // Adding child data
            var lstCS = new List<string>();
            lstCS.Add("Data structure");
            lstCS.Add("C# Programming");
            lstCS.Add("Java programming");
            lstCS.Add("ADA");
            lstCS.Add("Operation reserach");
            lstCS.Add("OOPS with C");
            lstCS.Add("C++ Programming");
    
            var lstEC = new List<string>();
            lstEC.Add("Field Theory");
            lstEC.Add("Logic Design");
            lstEC.Add("Analog electronics");
            lstEC.Add("Network analysis");
            lstEC.Add("Micro controller");
            lstEC.Add("Signals and system");
    
            var lstMech = new List<string>();
            lstMech.Add("Instrumentation technology");
            lstMech.Add("Dynamics of machinnes");
            lstMech.Add("Energy engineering");
            lstMech.Add("Design of machine");
            lstMech.Add("Turbo machine");
            lstMech.Add("Energy conversion");
    
            //Group, Child data
            _listChild.Add(_listGroup[0], lstCS);
            _listChild.Add(_listGroup[1], lstEC);
            _listChild.Add(_listGroup[2], lstMech);
        }
    }
    
Sign In or Register to comment.