Search code examples
c#listviewxamarin.android

How to fill ListView from IList Xamarin.Android c#?


Could you help me with filling ListView (different columns) (Xamarin.Android) from IList?

I have added data to IList - "readingList"

And now I am struggling to populate this in "lv".. I am just starting with Xamarin.Android on my defence :P

    IList<Readings> readingList = new List<Readings>();
    ListView lv;

private void FillData()
    {
        lv = FindViewById<Android.Widget.ListView>(Resource.Id.gvLora);


        try
        {
            Cn.OpenConnection();
            NpgsqlCommand cmd = new NpgsqlCommand("SELECT encode(device_up.data::bytea,'base64') as Data,f_port, received_at,application_name, device_name FROM device_up", Cn.connection);
            NpgsqlDataReader myReader = cmd.ExecuteReader();

            while (myReader.Read())
            {
                Readings rd = new Readings();
                rd.Data = (string)myReader["Data"];
                rd.Received = (DateTime)myReader["received_at"];
                rd.MeterNumber = (string)myReader["device_name"];
                rd.Application = (string)myReader["application_name"];
                rd.Port = (int)myReader["f_port"];
                readingList.Add(rd);
            }
            Cn.CloseConnection();


        }
        catch { }
    } 

x

    class Readings
{
    public string Data { get; set; }
    public DateTime Received { get; set; }
    public string MeterNumber { get; set; }
    public string Application { get; set; }
    public int Port { get; set; }
}

Thanks for any help!


Solution

  • First of all, please make sure you can get the data correctly to IList<Readings> readingList = new List<Readings>();, I cannot reproduce your project completely, So I used static data to fill the listview.

     public class MainActivity : AppCompatActivity
        {
            IList<Readings> readingList;
            ListView listView1;
            protected override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
                Xamarin.Essentials.Platform.Init(this, savedInstanceState);
                // Set our view from the "main" layout resource
                SetContentView(Resource.Layout.activity_main);
                listView1 = FindViewById<ListView>(Resource.Id.listView1);
                FillData();
                listView1.Adapter=new ReadingsAdapter(this, readingList);
                
            }
    
            private void FillData()
            {
                readingList = new List<Readings>();
    
                readingList.Add(new Readings { Data="test1", Received=DateTime.Now, Application= "Application1", MeterNumber="123", Port=8080 });
                readingList.Add(new Readings { Data = "test2", Received = DateTime.Now, Application = "Application2", MeterNumber = "1523", Port = 8081 });
                readingList.Add(new Readings { Data = "test3", Received = DateTime.Now, Application = "Application3", MeterNumber = "1223", Port = 8180 });
                readingList.Add(new Readings { Data = "test4", Received = DateTime.Now, Application = "Application4", MeterNumber = "1423", Port = 8080 });
                readingList.Add(new Readings { Data = "test5", Received = DateTime.Now, Application = "Application5", MeterNumber = "1623", Port = 8380 });
                readingList.Add(new Readings { Data = "test6", Received = DateTime.Now, Application = "Application6", MeterNumber = "1723", Port = 8480 });
            }
    

    Based on your Readings model, you can create a BaseAdapter to fill you data.

        public class ReadingsAdapter : BaseAdapter<Readings>
        {
            MainActivity mcontext;
            IList<Readings> list;
            public ReadingsAdapter(MainActivity context, IList<Readings>  list)
            {
                this.mcontext = context;
                this.list = list;
            }
            public override Readings this[int position] => list[position];
    
            public override int Count => list.Count;
    
            public override long GetItemId(int position)
            {
                return position;
            }
    
            public override View GetView(int position, View convertView, ViewGroup parent)
            {
    
                View view = convertView;
                if (view == null) // no view to re-use, create new
                    view  = mcontext.LayoutInflater.Inflate(Resource.Layout.list_item, null);
                    view.FindViewById<TextView>(Resource.Id.Data).Text= list[position].Data;
                    view.FindViewById<TextView>(Resource.Id.Received).Text = list[position].Received.ToString();
                    view.FindViewById<TextView>(Resource.Id.MeterNumber).Text = list[position].MeterNumber.ToString();
                    view.FindViewById<TextView>(Resource.Id.Application).Text = list[position].Application;
                    view.FindViewById<TextView>(Resource.Id.Port).Text = list[position].Port.ToString();
                return view;
            }
        }
    

    In the baseAdapter, you should create a custom item layout. Here is list_item.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="111"
            android:id="@+id/Data"
        />
     <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="111"
            android:id="@+id/Received"
        />
     <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="111"
            android:id="@+id/MeterNumber"
        />
     <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="111"
            android:id="@+id/Application"
        />
    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="111"
            android:id="@+id/Port"
        />
    </LinearLayout>
    
    

    Here is running screenshot.

    enter image description here

    Here is a detail doc about the how to use listview in xamarin android.

    https://learn.microsoft.com/en-us/xamarin/android/user-interface/layouts/list-view/customizing-appearance