简体   繁体   中英

Refresh Fragment From Activity After Updating Data on SQLite Xamarin Android

I got an issue with my Android program when updating user data on Fragment_profile . Fragment_Profile loads User profile data and contains an update button in which the button navigates to an activity called EditProfileActivity . Users can technically update the data but, after they save the updated data, the data still can't be updated. The old data still appear. I try to refresh the fragment by using OnResume() and add OnRestart on my EditProfileActivity.cs and OnPause both in fragment and activity but, still nothing. I am using Xamarin Android and develop it with C#. For more info, you can see what happened in the GIF My issue

So far, I've tried to code, and here's my code. Fragment_profile.cs

public class Fragment_Profile : Android.Support.V4.App.Fragment
    {
        public HomePageActivity m_currentActivity;

        public TextView m_tv_loginname, m_tv_username, m_tv_fullname , m_tv_dob;

        public Boolean isRefreshing = false;

        public override void OnCreate(Bundle aSavedInstanceState)
        {
            base.OnCreate(aSavedInstanceState);
        }

        //public static Fragment_Profile NewInstance(Model.User aCurrentUser)
        public static Fragment_Profile NewInstance()
        {
            var _frag4 = new Fragment_Profile { Arguments = new Bundle() };
            return _frag4;
        }

        public override View OnCreateView(LayoutInflater aInflater, ViewGroup aContainer, Bundle aSavedInstanceState)
        {
            var _ignored = base.OnCreateView(aInflater, aContainer, aSavedInstanceState);
            var view= aInflater.Inflate(Resource.Layout.FragmentProfile, null);

            m_tv_loginname = view.FindViewById<TextView>(Resource.Id.tv_loginname);
            m_tv_username = view.FindViewById<TextView>(Resource.Id.tv_userEmail);
            m_tv_fullname = view.FindViewById<TextView>(Resource.Id.tv_fullname);
            m_tv_dob = view.FindViewById<TextView>(Resource.Id.tv_dob);


            Button _updateProfile = view.FindViewById<Button>(Resource.Id.btnUpdateProfile);

            _updateProfile.Click += _updateProfile_Click;

            m_currentActivity = (HomePageActivity)this.Activity;

            if (m_currentActivity.CurrentUser != null)
            {
                //string  = "Welcome, " + m_currentActivity.CurrentUser.UserName;
                m_tv_loginname.Text = m_currentActivity.CurrentUser.LoginName;
                m_tv_fullname.Text = m_currentActivity.CurrentUser.UserName;
                m_tv_username.Text = m_currentActivity.CurrentUser.UserEmail;
                m_tv_dob.Text = m_currentActivity.CurrentUser.DateOfBirth;
            }

            else
            {
                Toast.MakeText(Activity, "The data is not found!", ToastLength.Short).Show();
                Intent i = new Intent(Context, typeof(MainActivity));
                StartActivity(i);
                this.Activity.Finish();
            }


            return view;
        }

        private void _updateProfile_Click(object sender, EventArgs e)
        {
            Intent i = new Intent(Context, typeof(EditProfileActivity));
            i.PutExtra("loginname", m_currentActivity.CurrentUser.LoginName);
            i.PutExtra("fullname", m_currentActivity.CurrentUser.UserName);
            i.PutExtra("useremail", m_currentActivity.CurrentUser.UserEmail);
            i.PutExtra("dob", m_currentActivity.CurrentUser.DateOfBirth);
            StartActivity(i);
        }

        public override void OnResume()
        {
            base.OnResume();
            if (isRefreshing)
            {
                Fragment fragment = new Fragment_Profile();
                Android.Support.V4.App.FragmentManager fragmentMg = Activity.SupportFragmentManager;
                FragmentTransaction fragmentTrans = fragmentMg.BeginTransaction();
                fragmentTrans.Replace(Resource.Id.content_frame, fragment);
                fragmentTrans.Detach(fragment);
                fragmentTrans.Attach(fragment);
                fragmentTrans.Commit();

                //adapter.notifyDataSetChanged();
            }
        }

        public override void OnPause()
        {
            base.OnPause();
                isRefreshing = true;
        }
    }

When user click the _updateProfile button It will reference to next activity which is EditProfileActivity. Here's my EditProfileActivity.cs

 public class EditProfileActivity : Activity, IOnDateSetListener
    {
        public EditText m_editFullName, m_editUsername, m_dob;
        public TextView m_tvEmail;
        public Button m_btnUpdate;
        public Boolean isRefreshing = false;



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

            SetContentView(Resource.Layout.EditProfile);

            m_editFullName = FindViewById<EditText>(Resource.Id.et_editfullName);
             m_editUsername = FindViewById<EditText>(Resource.Id.et_editUserName);
            m_tvEmail = FindViewById<TextView>(Resource.Id.tv_Email);
             m_dob = FindViewById<EditText>(Resource.Id.et_editDob);
            m_btnUpdate = FindViewById<Button>(Resource.Id.btn_updateprofile);

            m_btnUpdate.Click += _btnUpdate_Click;

            m_dob.Click += _dob_Click;

            Bundle extras = Intent.Extras;
            m_editFullName.Text = extras.GetString("loginname");
            m_editUsername.Text = extras.GetString("fullname");
            m_tvEmail.Text = extras.GetString("useremail");
            m_dob.Text = extras.GetString("dob");


        }

        private void _btnUpdate_Click(object sender, EventArgs e)
        {
            try
            {
                Model.User _currentUser = Model.User.CheckEmailUser(m_tvEmail.Text);
                _currentUser.UserName = m_editUsername.Text;
                _currentUser.LoginName = m_editFullName.Text;
                _currentUser.UserEmail = m_tvEmail.Text;
                _currentUser.DateOfBirth = m_dob.Text;

               var _updated =  DBManager.Instance.Update(_currentUser);

                if (_updated > 0)
                {

                    Toast.MakeText(this, "Your account has been succesfully updated!", ToastLength.Long).Show();
                    Finish();
                    OnResume();
                }

                else
                {
                       Toast.MakeText(this, "Failed to update!", ToastLength.Long).Show();
                }

            }

            catch(Exception ex)
            {
                Toast.MakeText(this, ex.ToString(), ToastLength.Short).Show();
            }
        }

        private void _dob_Click(object sender, EventArgs e)
        {
            var _dateTimeNow = DateTime.Now;
            DatePickerDialog _datepicker = new DatePickerDialog(this, this
                , _dateTimeNow.Year, _dateTimeNow.Month, _dateTimeNow.Day);
            _datepicker.Show();
        }

        public void OnDateSet(DatePicker view, int year, int month, int dayOfMonth)
        {
            m_dob.Text = new DateTime(year, month + 1, dayOfMonth).ToShortDateString();
        }

        protected override void OnRestart()
        {
            base.OnRestart();
            if (isRefreshing)
            {
                isRefreshing = false;
                Finish();
            }
        }

        protected override void OnPause()
        {
            base.OnPause();
            if (!isRefreshing)
                isRefreshing = true;
        }


    }

I also have read some articles that have the same problems as me but, It still confusing me and still same. I know it's a simple thing but, It took a few days for me because I am a newby and I still don't get the solution. Do you guys have any ideas? Would you like to help me? If you don't mind please check my source code so, I know what I am missing. Thank in advance for your help!

In you Fragment, you can override the OnResume method. If you back to the fragment from Acitivty. you should query the new data from DB, then set the new value to the controls in Fragment.

 public override void OnResume()
        {
            base.OnResume();
            PHName.Text = photoDAO.GetFirstPhotos(Id).PhotoName;
        }

Here is running GIF.

在此处输入图像描述

You can see this lifecycle about Fragment. Every time you display the Fragment, OnResume method will be executed. You get the newest data from DB, then set it to the Fragment page. 在此处输入图像描述

Here is my demo.

https://drive.google.com/file/d/11dROKS7TtqAaVYkG8w6ZKpqnQJRBD87E/view

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