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.

My DialogFragment does not close after using `this.Dismiss()`

Hi guys I have a little problem. I am using the support library and the navigation drawer, and for each item in the menu I have a separate fragment instead of activity. And a fragment can call a DialogFragment, which works fine, except if I for example open all 4 of my fragments before using the DialogFragment, I have to click the X button which closes the DF (with this.Dismiss) associated with it, which I found out is the relation to the problem. The more times I open a Fragment, this number of times I have to click the X button to close the DF.

Im using following code to display the fragments:

    private void ShowFragment(SupportFragment fragment)
    {
        if (fragment.IsVisible)
        {
            return;
        }

        var trans = SupportFragmentManager.BeginTransaction();

        trans.Replace(Resource.Id.LayoutFragmentHolder, fragment);
        trans.AddToBackStack(null);     
        trans.Commit();

        mCurrentFragment = fragment;
    }

Best Answer

  • cwphillicwphilli USMember ✭✭✭
    Accepted Answer

    I believe if you put a breakpoint in AddManually you will see that it is called once for every time you've called NavigationItemSelected.

    You should not be adding an event handler inside of NavigationItemSelected because it will add the event handler every time that NavigationItemSelected is called. (See the code += adding an additional handler every time).

    Moving it outside that scope should resolve your issue.

    private void SetUpDrawerContent(NavigationView navigationView)
    {
        fragmentDiet.OnDietAddManuallyClickComplete += delegate
        {
            AddManually();
        };
        fragmentDiet.OnDietScanClickComplete += delegate
        {
            Scan();
        };
        navigationView.NavigationItemSelected += (object sender, NavigationView.NavigationItemSelectedEventArgs e) =>
        {
            e.MenuItem.SetChecked(true);
            string itemTitle = e.MenuItem.TitleFormatted.ToString();
            switch (itemTitle)
            {
                case "Diet":
                    ShowFragment(fragmentDiet);
                    break;
                // ...
    

Answers

  • cwphillicwphilli USMember ✭✭✭

    I add a fragment with a tag (trans.Add(fragment, tag);) but before doing so I check to see if the fragment exists and remove it first.

    var prev = FragmentManager.FindFragmentByTag(tag);
    if (prev != null)
    {
        ft.Remove(prev);
    }
    

    You may also want to post your code that is showing the DialogFragment, because it sounds to me like the code that is showing your dialog fragment is called for every instance of fragment that you have, so a more complete code sample might help narrow down the problem.

  • MikolajMarciniak1991MikolajMarciniak1991 USMember ✭✭
        class DialogScanCreate : Android.App.DialogFragment
        {
            public ORM.Food Product;
    
            Context mContext;
    
            public DialogScanCreate(Context context, ORM.Food product)
            {
                mContext = context;
                Product = product;
            }
    
    
    
            public event EventHandler<OnSubmitClickEventArgs> OnSubmitClickComplete;
            public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
                base.OnCreateView(inflater, container, savedInstanceState);
    
                var view = inflater.Inflate(Resource.Layout.DialogScanCreate, container, false);
    
                string item;
    
                /*----------------------------------------------------------
                 * Spinner Start
                 *----------------------------------------------------------*/
    
                Spinner spinner = view.FindViewById<Spinner>(Resource.Id.spinnerChooseUnit);
    
                item = string.Format("{0}", spinner.GetItemAtPosition(0));
    
                /*
                 * When item is selected
                 * */
                spinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>((o,e)=> 
                {
    
                    /*
                     * Get selected item
                     * */
                    Product.Unit = string.Format("{0}",spinner.GetItemAtPosition(e.Position));
    
                });
                var adapter = ArrayAdapter.CreateFromResource(
                        mContext, Resource.Array.DialogScanCreateUnitsArray, Android.Resource.Layout.SimpleSpinnerItem);
    
                adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
                spinner.Adapter = adapter;
    
                /*----------------------------------------------------------
                 * Spinner End
                 *---------------------------------------------------------- */
    
                EditText editBarcode = view.FindViewById<EditText>(Resource.Id.editBarcode);
                editBarcode.Text = Product.Barcode != "" ? Product.Barcode : "";
    
                EditText editName = view.FindViewById<EditText>(Resource.Id.editName);
                editName.Text = Product.Name != "" ? Product.Name : "";
    
                EditText editAmount = view.FindViewById<EditText>(Resource.Id.editAmount);
                editAmount.Text = Product.Amount > 0 ? Product.Amount.ToString() : "";
    
                EditText editFats = view.FindViewById<EditText>(Resource.Id.editFats);
                editFats.Text = Product.Fats > 0 ? Product.Fats.ToString() : "";
    
                EditText editCarbs = view.FindViewById<EditText>(Resource.Id.editCarbs);
                editCarbs.Text = Product.Carbs > 0 ? Product.Carbs.ToString() : "";
    
                EditText editProtein = view.FindViewById<EditText>(Resource.Id.editProtein);
                editProtein.Text = Product.Protein > 0 ? Product.Protein.ToString() : "";
    
                EditText editKcal = view.FindViewById<EditText>(Resource.Id.editKcal);
                editKcal.Text = Product.KcalPer100 > 0 ? Product.KcalPer100.ToString() : "";
    
    
    
    
    
                /*
                 * When clicked
                 * */
    
    
                Button buttonCreate = view.FindViewById<Button>(Resource.Id.buttonCreate);
                buttonCreate.Click += delegate
                {
                    Product.Name = editName.Text;
                    Product.Barcode = editBarcode.Text;
                    Product.Amount = int.Parse(editBarcode.Text);
                    Product.KcalPer100 = int.Parse(editKcal.Text);
                    Product.Fats = int.Parse(editFats.Text);
                    Product.Carbs = int.Parse(editCarbs.Text);
                    Product.Protein = int.Parse(editCarbs.Text);
    
    
    
                    using (WebClient client = new WebClient())
                    {
                        string json = JsonConvert.SerializeObject(Product);
                        client.Headers[HttpRequestHeader.ContentType] = "application/json";
                        client.UploadString("http://www.zrelya.com/api/createProduct.php", json);
                    }
    
    
                    /*
                    OnSubmitClickComplete.Invoke(this, new OnSubmitClickEventArgs(
                        barcode, Name, KcalPer100, Fats, Carbs, Protein, Amount, Unit
                        ));
                        */
    
                    this.Dismiss();
                };
    
                Button buttonClose = view.FindViewById<Button>(Resource.Id.buttonClose);
                buttonClose.Click += delegate
                {
    
                    this.Dismiss();
                };
    
                return view;
            }
        }
    
  • MikolajMarciniak1991MikolajMarciniak1991 USMember ✭✭

    Thanks, Ill try doing so. Maybe the problem is with the DF...

  • cwphillicwphilli USMember ✭✭✭

    @MikolajMarciniak.2972 please also post the code where DialogScanCreate is called

  • MikolajMarciniak1991MikolajMarciniak1991 USMember ✭✭
        private void AddManually()
        {
            Android.App.FragmentTransaction transaction = FragmentManager.BeginTransaction();
            DialogScanCreate dialog = new DialogScanCreate(this, new ORM.Food());
            dialog.Show(transaction, "dialog");
        }
    

    And AddManually() is activated here:

        private void SetUpDrawerContent(NavigationView navigationView)
        {
            navigationView.NavigationItemSelected += (object sender, NavigationView.NavigationItemSelectedEventArgs e) =>
            {
                e.MenuItem.SetChecked(true);
                string itemTitle = e.MenuItem.TitleFormatted.ToString();
                switch (itemTitle)
                {
                    case "Diet":
                        ShowFragment(fragmentDiet);
                        fragmentDiet.OnDietAddManuallyClickComplete += delegate
                        {
                            AddManually();
                        };
                        fragmentDiet.OnDietScanClickComplete += delegate
                        {
                            Scan();
                        };
                        break;
    
                    case "Training":
                        ShowFragment(fragmentTraining);
    
                        break;
    
                    case "Settings":
                        ShowFragment(fragmentSettings);
    
                        break;
    
                    case "Profile":
                        ShowFragment(fragmentProfile);
                        break;
    
                    default:
                        ShowFragment(fragmentTraining);
                        break;
                }
    
    
                mDrawerLayout.CloseDrawers();
            };
        }
    
  • cwphillicwphilli USMember ✭✭✭
    Accepted Answer

    I believe if you put a breakpoint in AddManually you will see that it is called once for every time you've called NavigationItemSelected.

    You should not be adding an event handler inside of NavigationItemSelected because it will add the event handler every time that NavigationItemSelected is called. (See the code += adding an additional handler every time).

    Moving it outside that scope should resolve your issue.

    private void SetUpDrawerContent(NavigationView navigationView)
    {
        fragmentDiet.OnDietAddManuallyClickComplete += delegate
        {
            AddManually();
        };
        fragmentDiet.OnDietScanClickComplete += delegate
        {
            Scan();
        };
        navigationView.NavigationItemSelected += (object sender, NavigationView.NavigationItemSelectedEventArgs e) =>
        {
            e.MenuItem.SetChecked(true);
            string itemTitle = e.MenuItem.TitleFormatted.ToString();
            switch (itemTitle)
            {
                case "Diet":
                    ShowFragment(fragmentDiet);
                    break;
                // ...
    
  • MikolajMarciniak1991MikolajMarciniak1991 USMember ✭✭

    Yes, this indeed did resolve the issue. Thank you very much mate!

Sign In or Register to comment.