解雇排队的DialogFragments - 他们只是不断回来

时间:2017-02-20 20:27:58

标签: c# android android-fragments xamarin

我正在学习如何在Xamarin中开发一个Android应用程序,但实际上同样适用于Java原创。我正在尝试实现一个多对话框过程,通过该过程可以编辑数据库条目的某些功能。 我暂时有两个 - TimeChangeFragment和DateChangeFragment。我在我的MainActvity中创建它们并且分别有OnNewTimePass和OnNewDatePass接口,我通过它发回用户的输入并通知MainActvity它应该关闭这个DialogFragment,显示下一个等等。

代码如下:

对话框片段:

   public class TimeChangeDialog : DialogFragment
    {

        public int _id;
        ViewGroup _container;

        public interface OnNewTimePass
        {
            void onNewTimePass(DateTime date, int id);
            void openDateDialog(int id, Bundle savedInstanceState)
            void closeTimeDialog(ReminderTimeDialog dialog);
        }

        public OnNewTimePass dataPasser
        {
            get; set;
        }

        public static ReminderTimeDialog NewInstance(Bundle bundle)
        {
            ReminderTimeDialog fragment = new ReminderTimeDialog();
            fragment.Arguments = bundle;
            return fragment;
        }

        public override void OnAttach(Activity a)
        {
            base.OnAttach(a);
            dataPasser = (OnNewTimePass)a;
        }


        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            /*onCreate, inflateView, handle dataetc.*/
            Button buttonNext = view.FindViewById<Button>(Resource.Id.DialogButtonNext);


            buttonNext.Click += delegate {
                goToNext(view,savedInstanceState);
           //Dismiss();
            };
            return view;


        }


      public override void OnDismiss(IDialogInterface dialog)
        {
            base.OnDismiss(dialog);
            Dismiss();
        }


        public void goToNext(View view, Bundle savedInstanceState)
        {
            /* handle data here */
            dataPasser.onNewTimePass(_workingtime, _id);
            dataPasser.openDateDialog(_id, savedInstanceState);
            dataPasser.closeTimeDialog(this);
        }
    }
}

主要活动:(实现TimeChangeFragment.OnNewTimePass,

DateChangeFragment.OnNewDatePass) ###
    public void closeTimeDialog(dialog){
    FragmentTransaction ft = FragmentManager.BeginTransaction();
    ft.Remove(dialog);
    FragmentManager.addToBackStack('close-time');
    ft.Commit();

    //Also tried i.e. dialog.Dismiss(); here
    }
    public void openDateDialog(int id,Bundle bundle) {
                 FragmentTransaction ft = FragmentManager.BeginTransaction();
                  //Remove fragment
                  Fragment prev = FragmentManager.FindFragmentByTag("dialog");
                  if (prev != null)
                  {
                      ft.Remove(prev);
                  }

                  ft.AddToBackStack("date-dialog");
                // Create and show the dialog.

                TimeChangeFragment dateDialog = DateChangeFragment.NewInstance(taskdata);
                  dateDialog.Arguments = taskdata;
                  dateDialog.SetStyle(DialogFragmentStyle.NoTitle, 0);
                  dateDialog.Show(ft, "date-dialog");

    /*handle data here*/

            }

类似于DateChangeDialog,只有我没有调用openNextDialog()。

错误:

当我离开最后的对话框片段时,片刻,第一个片段重新出现,重新开始整个过程​​。

注意:

我已经在这里工作了几天,阅读了许多关于单一DialogFragments和类似问题的建议。我尝试了大部分。一个人说Fragment本身处理他们自己的事务,所以在他们内部调用Dismiss()是正确的方法(并覆盖OnDismiss())。但是,当我这样做时,即使在Dismiss()之前调用openDateDialog(),第二个片段也不会出现;或者,更加眩晕,它的OnAttach被调用,但对话框本身并没有出现。 我把所有的片段管理都留给了一个案例中的Main活动和另一个案例中的片段(甚至让第二个片段从第一个片段的主体内创建),但它似乎仍然存在。 我读过的一个建议是,需要将backstack弹出到没有对话框的状态,或者需要优先处理事务,而不是放在后台堆栈上。我试过后者无济于事。至于前者,我仍然不清楚交易应该在哪里处理。如果在MainActivity中,如何正确引用要关闭的对话框。如果在DialogFragment中,当它本身是活动的一部分时,如何获取FragmentManager?非常感谢您的任何答案。

1 个答案:

答案 0 :(得分:0)

  

当我离开最后的对话框片段时,片刻,第一个片段重新出现,重新开始整个过程​​。

第一次约会对话再次出现,因为你永远不会被解雇。

要解决此问题,您可以添加对第一个datedialog的引用,并在您关闭第二个对话框(timedialog)时将其关闭:

MainActivity:

public class MainActivity : Activity, ReminderDateDialog.OnNewDatePass,ReminderTimeDialog.OnNewTimePass//,taskedit_BaseFragment.OnChangeAddDataPass
{
    DateTime _tempDateTime = DateTime.MinValue;

    ReminderDateDialog dateDialog;// use a variable to temporarily store the date dialog
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        SetContentView(Resource.Layout.Main);
        var btnChange =FindViewById<Button>(Resource.Id.ReallySurelyAButton);

        btnChange.Click += delegate
        {
            openDateDialog(3,bundle);
        };
    }

    public void closeTimeDialog(ReminderTimeDialog dialog)
    {
        FragmentTransaction ft = FragmentManager.BeginTransaction();
         ft.Remove(dialog);
         ft.AddToBackStack("close-time");
         dialog.Dismiss();
        dateDialog.Dismiss();// dismiss the date dialog after the time dialog;
    }

    ...

}