简体   繁体   中英

How to populate a Listview in xamarin android c# using REST API, custom listview, adapter, row layout

I have very limited know how of programming in general. Trying to create a custom list view to display an image and a message mainly.

Ive been trying to follow tutorials on how to do it and cannot for the life of me work out how to make it work ..

currently have these errors and have no idea how to fix:

[![msgInbox screen error][1]][1]

This is the msgInbox activity with the list:

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

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Dribl;
using Newtonsoft.Json;

namespace Dribl.Droid
{
    [Activity(Label = "MsgInbox", Theme = "@style/CustomActionBarTheme")]
    public class MsgInbox : Activity
    {

        TextView txt;

        //Button backBtn;

        private List<Message> msgItems;

        private ListView msgListview;

        //private BaseAdapter<msgInfo> mAdapter;

        //action bar layout buttons
        LinearLayout surveysBtn;


        LinearLayout availabilityBtn;


        LinearLayout inboxBtn;


        LinearLayout dashboardBtn;




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

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.msgInbox);
            //add the action bar to the layout 
            ActionBar.SetCustomView(Resource.Layout.action_bar);
            ActionBar.SetDisplayShowCustomEnabled(true);



            //actionbar layout btns
            //actionbar layout btns
            surveysBtn = FindViewById<LinearLayout>(Resource.Id.SurveyLayout);
            surveysBtn.Click += surveyBtn_Click;

            inboxBtn = FindViewById<LinearLayout>(Resource.Id.InboxLayout);
            inboxBtn.Click += InboxBtn_Click;


            availabilityBtn = FindViewById<LinearLayout>(Resource.Id.availabilityLayout);
            availabilityBtn.Click += availabilityBtn_Click;

            dashboardBtn = FindViewById<LinearLayout>(Resource.Id.dashboardLayout);
            dashboardBtn.Click += dashboardBtn_Click;


            txt = FindViewById<TextView>(Resource.Id.msg_txt);


            WebClient client = new WebClient();
            System.Uri uri = new System.Uri("http://dribl.com/api/getAllMyMessages");
            NameValueCollection parameters = new NameValueCollection();


            parameters.Add("token", GlobalVariables.token);

            client.UploadValuesAsync(uri, parameters);
            client.UploadValuesCompleted += client_UploadValuesCompleted;

            //listview
            msgListview = FindViewById<ListView>(Resource.Id.msgListView);
            msgListview.ItemClick += MsgListview_ItemClick;


        }

        private void MsgListview_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            Intent intent = new Intent(this, typeof(msgDetails));

            //add in a variable to store the message that was clicked on and pass across to next pages txtfield
            intent.PutExtra("msgDet", "This is a message");
            StartActivity(intent);
        }

        protected internal void client_UploadValuesCompleted(object sender, UploadValuesCompletedEventArgs e)
        {
            string json = Encoding.UTF8.GetString(e.Result);
            List<Message> messages = JsonConvert.DeserializeObject<List<Message>>(json);

            //display the retrieved msg in the console output
            //Console.WriteLine(message[1].message + " is the message");

            //display the msg in a text view at top of page
            //txt.Text = message[1].message;


            //get the list view create a string to store and add to the list view based on the json return

            // msgItems = new List<Message>();

            // for (int c = 0; c < message.Count; c++)
            // {

            //     msgItems.Add(message[c].message);
            //msgItems.Add(new Message() { message = "pauls hectic"});
            //}

            msgItems = messages;

           // msgAdapter msgAdapter = new msgAdapter(this, msgItems);
            //msgListview.Adapter = msgAdapter;


            //Msgs.Add(message[1].message);
            //Msgs.Add(message[0].message);

           // ArrayAdapter<Message> adapter = new ArrayAdapter<Message>(this, Android.Resource.Layout.SimpleListItem1, msgItems);
            //msgListview.Adapter = adapter;
           // msgAdapter msgAdapter = new MsgAdapter(this, message);
            //var msgAdapter = new MsgAdapter(this, message);
            MsgAdapter msgAdapter = new MsgAdapter(this, messages);
        }


        void surveyBtn_Click(object sender, EventArgs e)
        {
            Intent intent = new Intent(this, typeof(Surveys));
            this.StartActivity(intent);
            this.Finish();
        }

        void dashboardBtn_Click(object sender, EventArgs e)
        {
            Intent intent = new Intent(this, typeof(dashboard));
            this.StartActivity(intent);
            this.Finish();
        }

        void availabilityBtn_Click(object sender, EventArgs e)
        {
            Intent intent = new Intent(this, typeof(Availability));
            this.StartActivity(intent);
            this.Finish();
        }

        void InboxBtn_Click(object sender, EventArgs e)
        {
            Intent intent = new Intent(this, typeof(MsgInbox));
            this.StartActivity(intent);
            this.Finish();
        }





    }


}

This is the msgInfo class:

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 Dribl.Droid
{

            public class Message
        {

            public string messages { get; set; }


    }

}

This is the msg Adapter:

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 Dribl.Droid
{


    class MsgAdapter : BaseAdapter<Message>
    {
        private List<Message> msgItems;
        private Context msgContext;

        public MsgAdapter(Context Context, List<Message> Items)
        {
            msgItems = Items;
            msgContext = Context;
        }
        public override int Count
        {
            get { return msgItems.Count; }
        }
        public override long GetItemId(int position)
        {
            return position;
        }
        public override Message this[int position]
        {
            get { return msgItems[position]; }
        }
        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            View row = convertView;

            if (row == null)
            {
                row = LayoutInflater.From(msgContext).Inflate(Resource.Layout.msgCell, parent, false);
            }


            TextView message = row.FindViewById<TextView>(Resource.Id.message);
            message.Text = msgItems[position].messages;

            return row;
        }
    }
}
List<Message> message = JsonConvert.DeserializeObject<List<Message>>(json);

message is already a list of messages List<Message> so you don't need to create a new one. Just pass this object to the adapter constructor.

You can remove this part:

       msgItems = new List<Message>();

        for (int c = 0; c < message.Count; c++)
        {
            msgItems.Add(message[c].message);
        }

But in case you wanna hold the list of message you just need to:

msgItems = messages;

Then creating you adapter object:

msgAdapter adapter = new msgAdapter(this, message);

or you can also

var adapter = new msgAdapter(this, message);

and add the adapter:

msgListview.Adapter = adapter;

Notes:

Change the message variable to messages since this contains more than one message.

msgAdapter change the name to MsgAdapter (First letter in capital) this way you won't have problems finding out when it's the class and when it's the object.

UPDATE:

You have an error in the GetView method of your adapter.

You need to indicate the parent when inflating the row:

row = LayoutInflater.From(msgContext).Inflate(Resource.Layout.msgCell, parent, false);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM