【问题标题】:Xamarin.Android DialogFragment some LifeCycle Events not firingXamarin.Android DialogFragment 一些生命周期事件未触发
【发布时间】:2018-01-11 05:22:16
【问题描述】:

我在使用 Xamarin.Android 时遇到问题(请参阅下面的代码)

MainActivity.cs:

using Android.App;
using Android.Widget;
using Android.OS;

namespace DialogFragmentLife
{
    [Activity(Label = "DialogFragmentLife", MainLauncher = true)]
    public class MainActivity : Activity
    {
        private Button _btnShowDF;
        private DialogFragmentLife _dfLife;

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

            SetContentView(Resource.Layout.Main);

            _btnShowDF = FindViewById<Button>(Resource.Id.btnShowDF);
            _btnShowDF.Click += _btnShowDF_Click;
        }

        private void _btnShowDF_Click(object sender, System.EventArgs e)
        {
            _dfLife = new DialogFragmentLife(this);

            _dfLife.Show(FragmentManager, "dfLife");
        }
    }
}

还有下面的DialogFragmentLife.cs

using Android.App;
using Android.Content;
using Android.OS;
using Android.Views;

namespace DialogFragmentLife
{
    class DialogFragmentLife : DialogFragment
    {
        private Context _context;

        public DialogFragmentLife(Context context)
        {
            _context = context;
        }

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            base.OnCreateView(inflater, container, savedInstanceState);

            RetainInstance = true;

            View view = inflater.Inflate(Resource.Layout.DialogFragmentLife, container, false);

            return view;
        }

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

        public override void OnPause()
        {
            base.OnPause();
        }

        public override void OnStop()
        {
            base.OnStop();
        }

        public override void OnHiddenChanged(bool hidden)
        {
            base.OnHiddenChanged(hidden);
        }

        public override void OnDestroyView()
        {
            Dialog dialog = Dialog;

            if (dialog != null && RetainInstance)
                dialog.SetDismissMessage(null);

            base.OnDestroyView();
        }

        public override void OnDetach()
        {
            base.OnDetach();
        }

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

一切都按预期工作,除了 DialogFragment 的生命周期事件在被解除或设备旋转(方向改变)时,没有任何 LifeCycle 事件被触发。

正如你在代码中看到的,

  • 关闭
  • 暂停
  • OnStop
  • OnHiddenChanged
  • OnDestroyView
  • OnDetach
  • 开取消

他们都没有被解雇。不知道有没有人遇到同样的问题。

【问题讨论】:

    标签: android xamarin xamarin.android dialogfragment


    【解决方案1】:

    方向不影响对话框片段生命周期。

    • DialogFragment 做各种事情来保持片段的生命周期驱动它,而不是 Dialog。请注意,对话框通常是自治实体——它们是自己的窗口,接收自己的输入事件,并且通常自行决定何时消失(通过接收后退键事件或用户单击按钮)。

    • DialogFragment 需要确保 Fragment 和 Dialog 状态发生的情况保持一致。为此,它会监视对话框中的事件,并在它们发生时负责删除自己的状态。这意味着您应该使用 Show(FragmentManager, String) 或 Show(FragmentTransaction, String) 将 DialogFragment 的实例添加到您的 UI,因为它们会跟踪 DialogFragment 在对话框关闭时应如何自行删除。

      李> 1234563 ,您在这里没有注意到的是,在方向更改时,将调用活动的生命周期事件而不是对话框片段,一个片段不会以任何方式影响另一个片段的生命周期。
    • 有关使用生命周期的信息,请查看this out。这个家伙对 Android(Activity 和 Fragment)生命周期的各个方面进行了精美的分析。

    • onActivityCreated: 当片段的活动被创建并且这个片段的视图层次被实例化时调用。一旦这些部分到位,它就可以用来进行最终初始化,例如检索视图或恢复状态。它对于使用 setRetainInstance(boolean) 来保留其实例的片段也很有用,因为此回调告诉片段何时与新活动实例完全关联。这在 onCreateView(LayoutInflater, ViewGroup, Bundle) 之后和 onViewStateRestored(Bundle) 之前调用。

    • onAttach:在片段首次附加到其上下文时调用。 onCreate(Bundle) 将在此之后被调用。

    • onCancel:对话框取消时会调用此方法。

    • onCreate:调用以执行片段的初始创建。这在 onAttach(Activity) 和 onCreateView(LayoutInflater, ViewGroup, Bundle) 之前调用,但如果片段实例在 Activity 重新创建期间保留(请参阅 setRetainInstance(boolean)),则不会调用它。 请注意,可以在片段的活动仍在创建过程中时调用它。因此,您不能依赖于此时正在初始化的活动的内容视图层次结构之类的东西。如果您想在活动本身创建后开始工作,请参阅 onActivityCreated(Bundle)。 如果您的应用的 targetSdkVersion 为 M 或更低,则从 savedInstanceState 恢复的子片段会在 onCreate 返回后恢复。当面向 N 或更高版本并在 N 或更新的平台版本上运行时,它们由 Fragment.onCreate 恢复。

    • onCreateDialog:覆盖以构建您自己的自定义对话框容器。这通常用于显示 AlertDialog 而不是通用 Dialog;这样做时,不需要实现 onCreateView(LayoutInflater, ViewGroup, Bundle),因为 AlertDialog 会处理自己的内容。 此方法将在 onCreate(Bundle) 之后和 onCreateView(LayoutInflater, ViewGroup, Bundle) 之前调用。默认实现只是实例化并返回一个 Dialog 类。 注意:DialogFragment 拥有 Dialog.setOnCancelListener 和 Dialog.setOnDismissListener 回调。你不能自己设置它们。要了解这些事件,请覆盖 onCancel(DialogInterface) 和 onDismiss(DialogInterface)。

    • onDestroyView:删除对话框。

    • onDetach:当片段不再附加到其活动时调用。这在 onDestroy() 之后调用,除非片段实例在 Activity 重新创建期间保留(参见 setRetainInstance(boolean)),在这种情况下,它在 onStop() 之后调用。

    • onDismiss:对话框关闭时会调用此方法。

    • onSaveInstanceState:调用该片段以要求片段保存其当前动态状态,以便稍后在其进程的新实例重新启动时对其进行重构。如果稍后需要创建片段的新实例,那么您在此处放置在 Bundle 中的数据将在提供给 onCreate(Bundle)、onCreateView(LayoutInflater, ViewGroup, Bundle) 和 onActivityCreated(Bundle) 的 Bundle 中可用。 这对应于 Activity.onSaveInstanceState(Bundle) 并且那里的大部分讨论也适用于这里。但是请注意:可以在 onDestroy() 之前的任何时间调用此方法。在很多情况下,一个片段可能大部分都被拆除了(例如当放置在没有显示 UI 的后台堆栈时),但它的状态不会被保存,直到它拥有的 Activity 实际需要保存它的状态。

    • onStart:当 Fragment 对用户可见时调用。这通常与包含 Activity 生命周期的 Activity.onStart 相关联。

    • onStop:在 Fragment 不再启动时调用。这通常与包含 Activity 生命周期的 Activity.onStop 相关联。

    Referred from here

    【讨论】:

    • 谢谢,但不幸的是,即使我关闭或取消或按下返回按钮,当 DialogFragment 消失时,上面提到的 OnDismiss、OnDestroyView 等事件都不会被触发
    • 您应该使用 appcompat 这可能是原因之一,因为您的设备可能是导致此错误的旧设备,因此请安装支持库以实现向后兼容性。
    • 谢谢,我已经使用了 AppCompat 并且事件被触发了 :)
    【解决方案2】:

    在网络上进行了更多搜索之后,我现在通过执行以下操作来触发一些事件:

    MainActivity.cs 我改变了

    using Android.App;
    

    using Android.Support.V7.App;
    

    然后,在 DialogFragmentLife.cs 我改变了

    using Android.App;
    

    using Android.Support.V4.App;
    

    最后,回到 MainActivity.cs,而不是使用显示 DialogFragment

    _dfLife.Show(FragmentManager, "dfLife");
    

    我将其更改为使用 SupportFragmentManager,如下所示

    _dfLife.Show(SupportFragmentManager, "dfLife");
    

    从那里开始,OnDestroyView() 现在在我旋转屏幕时被触发,在关闭对话框片段时也是如此

    【讨论】:

    • 还有!要保留元素,例如 EditText 上的文本,我发现您需要在元素上指定一个 ID。
    猜你喜欢
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多