Forum Xamarin.Android
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

How do I update a ListView?

mikoomikoo DKMember ✭✭
edited June 2017 in Xamarin.Android

Hi guys I have a problem. I have a DialogFragment with content that is saved in a sqlite db on the phone, and a Fragment that retrieves the information and shows it. The ListView initially (upon creation) shows everything like its supposed to, but when the stuff is updated inside the Dialog Fragment, I dont know how to update the adapter for ListView. Here is my code:

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.Util;
using Android.Views;
using Android.Widget;

namespace Zrelya.Fragments
{
    public class OnSelectedEventArgs : EventArgs
    {
        public ORM.Plan Plan { get; set; }

        public OnSelectedEventArgs( ORM.Plan plan )
        {
            Plan = plan;
        }
    }

    public class ViewPlans : FragmentSuper
    {
        private Context mContext;
        private ORM.DBRep dbr;

        public EventHandler<OnSelectedEventArgs> OnSelected;

        public ViewPlans(Context context)
        {
            mContext = context;
        }

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

            // Create your fragment here

            dbr = new ORM.DBRep();
        }

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            // Use this to return your custom view for this Fragment
            var view = inflater.Inflate(Resource.Layout.ViewPlans, container, false);
            var listView = view.FindViewById<ListView>(Resource.Id.listView);


            List<ORM.Plan> plansList = dbr.GetPlans();
            Adapters.Plan adapter = new Adapters.Plan(mContext, plansList);
            listView.Adapter = adapter;

            listView.ItemClick += (o, e) =>
            {
                int id = plansList[e.Position].Id;

                OnSelected.Invoke(this, new OnSelectedEventArgs(plansList[e.Position]));
            };

            return view;
        }
    }
}

OnSelected.Invoke is what happens when an item is clicked, showing the fragment. The following code is a snippet from MainActivity OnCreate method:

        fragmentViewPlans.OnSelected += (o, e) =>
        {
            int id = e.Plan.Id;
            DialogViewPlan(e.Plan);
        };

...and the DialogViewPlan method is below:

    private void DialogViewPlan(ORM.Plan plan)
    {
        if (plan != null)
        {
            Android.App.FragmentTransaction transaction = FragmentManager.BeginTransaction();
            Helpers.DialogViewPlan dialog = new Helpers.DialogViewPlan(this, plan);
            dialog.Show(transaction, "dialog");
            dialog.OnDelete += delegate
            {
                Toast.MakeText(this, "Plan deleted...", ToastLength.Short).Show();
            };
            dialog.OnSave += delegate
            {
                Toast.MakeText(this, "Plan saved!", ToastLength.Short).Show();
            };

        }
    }

I dont know how to talk between activity, fragment and dialog fragment, does anyone know how to do this?

Best Answer

  • mikoomikoo DKMember ✭✭
    Accepted Answer

    I did it. I put the dialog fragment inside the fragment class and passed the variables there:

    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Views;
    using Android.Widget;
    using System;
    using System.Collections.Generic;
    
    namespace Zrelya.Fragments
    {
        public class OnSelectedEventArgs : EventArgs
        {
            public ORM.Plan Plan { get; set; }
    
            public OnSelectedEventArgs( ORM.Plan plan )
            {
                Plan = plan;
            }
        }
    
        public class ViewPlans : FragmentSuper
        {
            private Context mContext;
            private ORM.DBRep dbr;
    
            private static Adapters.Plan Adapter;
            private static ListView listView;
    
            public EventHandler<OnSelectedEventArgs> OnSelected;
    
            public ViewPlans(Context context)
            {
                mContext = context;
            }
    
            public override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
    
                // Create your fragment here
    
                dbr = new ORM.DBRep();
            }
    
            public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
                // Use this to return your custom view for this Fragment
                var view = inflater.Inflate(Resource.Layout.ViewPlans, container, false);
                listView = view.FindViewById<ListView>(Resource.Id.listView);
    
    
                List<ORM.Plan> plansList = dbr.GetPlans();
                Adapter = new Adapters.Plan(mContext, plansList);
    
    
                listView.Adapter = Adapter;
    
    
                listView.ItemClick += (o, e) =>
                {
                    int id = plansList[e.Position].Id;
    
                    var plan = plansList[e.Position];
    
                    DialogViewPlan(plan);
    
                    //OnSelected.Invoke(this, new OnSelectedEventArgs(plansList[e.Position]));
                };
    
                return view;
            }
    
            private void DialogViewPlan(ORM.Plan plan)
            {
                if (plan != null)
                {
                    FragmentTransaction transaction = Activity.FragmentManager.BeginTransaction();
                    Helpers.DialogViewPlan dialog = new Helpers.DialogViewPlan(Activity, plan);
                    dialog.Show(transaction, "dialog");
                    dialog.OnDelete += delegate
                    {
                        ORM.DBRep dbr = new ORM.DBRep();
                        dbr.DeletePlan(plan);
                        Adapter.NotifyDataSetChanged();
                        Adapter = new Adapters.Plan(mContext, dbr.GetPlans());
                        listView.Adapter = Adapter;
                    };
                    dialog.OnSave += delegate
                    {
    
                    };
    
                }
            }
        }
    }
    

Answers

  • TripleDoubleTripleDouble BGMember ✭✭✭

    {
    Toast.MakeText(this, "Plan deleted...", ToastLength.Short).Show();
    NotifyDataSetChanged();
    };
    dialog.OnSave += delegate
    {
    Toast.MakeText(this, "Plan saved!", ToastLength.Short).Show();
    NotifyDataSetChanged();
    };

  • mikoomikoo DKMember ✭✭

    I cant do that , because the adapter is in a Fragment, and saving and deleting is in a separate DialogFragment, both managed by the MainActivity.

  • mikoomikoo DKMember ✭✭

    bump

  • DimChrisDimChris USMember ✭✭✭✭
    edited June 2017

    Here is an example of how i use a dialogfragment
    Here is my class

        public class CreateContactEventArgs : EventArgs
    {
        public string txtTableNumber { get; set; }
    
        public CreateContactEventArgs(string newtablenumber)
        {
            txtTableNumber = newtablenumber;
    
        }
    }
    class NumPadClass : DialogFragment
    {
        private Button mButtonCreateContact;
        private Button mButtonCreateCancel;
        private EditText txtTableNumber;
        public event EventHandler<CreateContactEventArgs> OnCreateContact;
        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            base.OnCreateView(inflater, container, savedInstanceState);
            var view = inflater.Inflate(Resource.Layout.NumPad, container, false);
            mButtonCreateContact = view.FindViewById<Button>(Resource.Id.OKButton);
            mButtonCreateCancel = view.FindViewById<Button>(Resource.Id.CancelButton);
            txtTableNumber = view.FindViewById<EditText>(Resource.Id.NewTableNumber);
    
    
            mButtonCreateContact.Click += mButtonCreateContact_Click;
            mButtonCreateCancel.Click += MButtonCreateCancel_Click;
            return view;
        }
        public override void OnActivityCreated(Bundle savedInstanceState)
        {
            Dialog.Window.RequestFeature(WindowFeatures.NoTitle);
            base.OnActivityCreated(savedInstanceState);
    
        }
    
        private void MButtonCreateCancel_Click(object sender, EventArgs e)
        {
            this.Dismiss();
        }
    
    
        void mButtonCreateContact_Click(object sender, EventArgs e)
        {
    
            if (OnCreateContact != null)
            {
                //Broadcast event
                OnCreateContact.Invoke(this, new CreateContactEventArgs(txtTableNumber.Text));
            }
    
            this.Dismiss();
    
    
    
        }
    }
    

    }

    And this is in my main Activity

        private void Button1_Click(object sender, EventArgs e)
        {
    
                NumPadClass dialog = new NumPadClass();
                FragmentTransaction transaction = FragmentManager.BeginTransaction();
                dialog.OnCreateContact += dialog_OnCreateContact;
                dialog.Show(transaction, "New TableNumber");
    
        }
        void dialog_OnCreateContact(object sender, CreateContactEventArgs e)
        {
    
            if (e.txtTableNumber != "") // e.txtTableNumber is assign it into my class and then i use it in my Activity
            {
    
            }
        }
    

    This Tutotial will be very usefull

  • mikoomikoo DKMember ✭✭

    Joe is good, Problem is that i have one activity with the navigation drawer layout, and each menu item is a fragment, which can have buttons to go to another fragment. when I enter the fragment with the listview, and click on an item, the fragment triggers an event which is captured by the main activity (code snippet from above), and it in turns opens a dialog fragment with a delete button. when i press delete, i expect on a high level to make the corresponding item from the list view disappear. i just dont know how to do it. im thinking through an event or by passing a variable or something, i dont know really.

  • mikoomikoo DKMember ✭✭
    Accepted Answer

    I did it. I put the dialog fragment inside the fragment class and passed the variables there:

    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Views;
    using Android.Widget;
    using System;
    using System.Collections.Generic;
    
    namespace Zrelya.Fragments
    {
        public class OnSelectedEventArgs : EventArgs
        {
            public ORM.Plan Plan { get; set; }
    
            public OnSelectedEventArgs( ORM.Plan plan )
            {
                Plan = plan;
            }
        }
    
        public class ViewPlans : FragmentSuper
        {
            private Context mContext;
            private ORM.DBRep dbr;
    
            private static Adapters.Plan Adapter;
            private static ListView listView;
    
            public EventHandler<OnSelectedEventArgs> OnSelected;
    
            public ViewPlans(Context context)
            {
                mContext = context;
            }
    
            public override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
    
                // Create your fragment here
    
                dbr = new ORM.DBRep();
            }
    
            public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
                // Use this to return your custom view for this Fragment
                var view = inflater.Inflate(Resource.Layout.ViewPlans, container, false);
                listView = view.FindViewById<ListView>(Resource.Id.listView);
    
    
                List<ORM.Plan> plansList = dbr.GetPlans();
                Adapter = new Adapters.Plan(mContext, plansList);
    
    
                listView.Adapter = Adapter;
    
    
                listView.ItemClick += (o, e) =>
                {
                    int id = plansList[e.Position].Id;
    
                    var plan = plansList[e.Position];
    
                    DialogViewPlan(plan);
    
                    //OnSelected.Invoke(this, new OnSelectedEventArgs(plansList[e.Position]));
                };
    
                return view;
            }
    
            private void DialogViewPlan(ORM.Plan plan)
            {
                if (plan != null)
                {
                    FragmentTransaction transaction = Activity.FragmentManager.BeginTransaction();
                    Helpers.DialogViewPlan dialog = new Helpers.DialogViewPlan(Activity, plan);
                    dialog.Show(transaction, "dialog");
                    dialog.OnDelete += delegate
                    {
                        ORM.DBRep dbr = new ORM.DBRep();
                        dbr.DeletePlan(plan);
                        Adapter.NotifyDataSetChanged();
                        Adapter = new Adapters.Plan(mContext, dbr.GetPlans());
                        listView.Adapter = Adapter;
                    };
                    dialog.OnSave += delegate
                    {
    
                    };
    
                }
            }
        }
    }
    
Sign In or Register to comment.