Xamarin.Android DialogFragment 一些生命周期事件没有触发
Xamarin.Android DialogFragment some LifeCycle Events not firing
我在使用 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 的生命周期事件,当它被关闭时,或者当设备旋转(方向改变)时,none生命周期事件被触发。
如您在代码中所见,
- 关闭
- 暂停
- 停止
- OnHiddenChanged
- OnDestroyView
- OnDetach
- 取消
None 人被解雇了。我想知道是否有人遇到同样的问题。
方向不影响对话框片段生命周期。
DialogFragment 做各种事情来保持片段的生命周期驱动它,而不是对话框。请注意,对话框通常是自治实体——它们是自己的 window,接收自己的输入事件,并且通常自行决定何时消失(通过接收返回键事件或用户单击按钮)。
DialogFragment 需要确保 Fragment 和 Dialog 状态发生的情况保持一致。为此,它会监视从对话框中消除的事件,并在事件发生时负责删除自己的状态。这意味着您应该使用 Show(FragmentManager, String) 或 Show(FragmentTransaction, String) 将 DialogFragment 的实例添加到您的 UI,因为它们会跟踪 DialogFragment 在关闭对话框时应如何自行删除。
另外,要知道某些生命周期方法依赖于调用其他方法,例如:OnDestroy 和 OnDestroyView 依赖于 Dismiss 或关闭后退按钮或关闭任何意义上的片段,您在这里没有注意到的是,在方向更改时将调用 activity 的生命周期事件,而不是对话框片段,一个片段不会以任何方式影响另一个片段的生命周期。
有关使用生命周期的信息,请查看 this out.This 这家伙对 Android( Activity& Fragment) 生命周期的各个方面进行了精美的分析.
在Activity创建:
在片段的 activity 已创建且此片段的视图层次结构已实例化时调用。一旦这些部分到位,它就可以用于进行最终初始化,例如检索视图或恢复状态。它对于使用 setRetainInstance(boolean) 保留其实例的片段也很有用,因为此回调会告诉片段何时与新的 activity 实例完全关联。这是在 onCreateView(LayoutInflater, ViewGroup, Bundle) 之后和 onViewStateRestored(Bundle) 之前调用的。
onAttach:片段首次附加到其上下文时调用。 onCreate(Bundle) 将在这之后被调用。
onCancel: 对话框取消时调用此方法
onCreate:调用以执行片段的初始创建。这在 onAttach(Activity) 之后和 onCreateView(LayoutInflater, ViewGroup, Bundle) 之前调用,但如果片段实例在 Activity 重新创建期间保留,则不会调用(请参阅 setRetainInstance(boolean))。
请注意,这可以在片段的 activity 仍在创建过程中调用。因此,您不能依赖于此时正在初始化的 activity 内容视图层次结构之类的东西。如果您想在 activity 本身创建后进行工作,请参阅 onActivityCreated(Bundle)。
如果您应用的 targetSdkVersion 为 M 或更低版本,则从 savedInstanceState 恢复的子片段将在 onCreate returns 之后恢复。当针对 N 或更高版本以及 运行 在 N 或更新的平台版本上时,它们由 Fragment.onCreate.
恢复
onCreateDialog:覆盖以构建您自己的自定义对话框容器。这通常用于显示 AlertDialog 而不是通用对话框;这样做时,不需要实现 onCreateView(LayoutInflater, ViewGroup, Bundle),因为 AlertDialog 会处理自己的内容。
此方法将在 onCreate(Bundle) 之后和 onCreateView(LayoutInflater, ViewGroup, Bundle) 之前调用。默认实现只是实例化和 returns 一个对话框 class。
注意:DialogFragment 拥有 Dialog.setOnCancelListener 和 Dialog.setOnDismissListener 回调。你不能自己设置它们。要了解这些事件,请覆盖 onCancel(DialogInterface) 和 onDismiss(DialogInterface)。
onDestroyView: 删除对话框。
onDetach:当片段不再附加到其 activity 时调用。这在 onDestroy() 之后调用,除非片段实例在 Activity 重新创建期间保留(请参阅 setRetainInstance(boolean)),在这种情况下它在 onStop() 之后调用。
onDismiss: 当对话框关闭时调用此方法。
onSaveInstanceState:调用以要求片段保存其当前动态状态,以便稍后在其进程重新启动的新实例中重建。如果稍后需要创建片段的新实例,那么您在此处放置在 Bundle 中的数据将在给 onCreate(Bundle)、onCreateView(LayoutInflater, ViewGroup, Bundle) 和 onActivity 的 Bundle 中可用创建(捆绑)。
这对应于 Activity.onSaveInstanceState(Bundle),那里的大部分讨论也适用于此处。但是请注意:这个方法可以在 onDestroy() 之前的任何时候被调用。在很多情况下,一个片段可能大部分都被拆除了(比如当放在返回堆栈上没有 UI 显示时),但它的状态不会被保存,直到它拥有的 activity 实际需要保存它的状态。
onStart:当Fragment对用户可见时调用。这通常与包含 Activity 的生命周期的 Activity.onStart 有关。
onStop:当Fragment不再启动时调用。这通常与包含 Activity 生命周期的 Activity.onStop 有关。
在网上进行了更多搜索后,我现在通过执行以下操作设法触发了一些事件:
在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() 现在会在我旋转屏幕时触发,在关闭对话框片段时也会触发
我在使用 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 的生命周期事件,当它被关闭时,或者当设备旋转(方向改变)时,none生命周期事件被触发。
如您在代码中所见,
- 关闭
- 暂停
- 停止
- OnHiddenChanged
- OnDestroyView
- OnDetach
- 取消
None 人被解雇了。我想知道是否有人遇到同样的问题。
方向不影响对话框片段生命周期。
DialogFragment 做各种事情来保持片段的生命周期驱动它,而不是对话框。请注意,对话框通常是自治实体——它们是自己的 window,接收自己的输入事件,并且通常自行决定何时消失(通过接收返回键事件或用户单击按钮)。
DialogFragment 需要确保 Fragment 和 Dialog 状态发生的情况保持一致。为此,它会监视从对话框中消除的事件,并在事件发生时负责删除自己的状态。这意味着您应该使用 Show(FragmentManager, String) 或 Show(FragmentTransaction, String) 将 DialogFragment 的实例添加到您的 UI,因为它们会跟踪 DialogFragment 在关闭对话框时应如何自行删除。
另外,要知道某些生命周期方法依赖于调用其他方法,例如:OnDestroy 和 OnDestroyView 依赖于 Dismiss 或关闭后退按钮或关闭任何意义上的片段,您在这里没有注意到的是,在方向更改时将调用 activity 的生命周期事件,而不是对话框片段,一个片段不会以任何方式影响另一个片段的生命周期。
有关使用生命周期的信息,请查看 this out.This 这家伙对 Android( Activity& Fragment) 生命周期的各个方面进行了精美的分析.
在Activity创建: 在片段的 activity 已创建且此片段的视图层次结构已实例化时调用。一旦这些部分到位,它就可以用于进行最终初始化,例如检索视图或恢复状态。它对于使用 setRetainInstance(boolean) 保留其实例的片段也很有用,因为此回调会告诉片段何时与新的 activity 实例完全关联。这是在 onCreateView(LayoutInflater, ViewGroup, Bundle) 之后和 onViewStateRestored(Bundle) 之前调用的。
onAttach:片段首次附加到其上下文时调用。 onCreate(Bundle) 将在这之后被调用。
onCancel: 对话框取消时调用此方法
onCreate:调用以执行片段的初始创建。这在 onAttach(Activity) 之后和 onCreateView(LayoutInflater, ViewGroup, Bundle) 之前调用,但如果片段实例在 Activity 重新创建期间保留,则不会调用(请参阅 setRetainInstance(boolean))。 请注意,这可以在片段的 activity 仍在创建过程中调用。因此,您不能依赖于此时正在初始化的 activity 内容视图层次结构之类的东西。如果您想在 activity 本身创建后进行工作,请参阅 onActivityCreated(Bundle)。 如果您应用的 targetSdkVersion 为 M 或更低版本,则从 savedInstanceState 恢复的子片段将在 onCreate returns 之后恢复。当针对 N 或更高版本以及 运行 在 N 或更新的平台版本上时,它们由 Fragment.onCreate.
恢复
onCreateDialog:覆盖以构建您自己的自定义对话框容器。这通常用于显示 AlertDialog 而不是通用对话框;这样做时,不需要实现 onCreateView(LayoutInflater, ViewGroup, Bundle),因为 AlertDialog 会处理自己的内容。 此方法将在 onCreate(Bundle) 之后和 onCreateView(LayoutInflater, ViewGroup, Bundle) 之前调用。默认实现只是实例化和 returns 一个对话框 class。 注意:DialogFragment 拥有 Dialog.setOnCancelListener 和 Dialog.setOnDismissListener 回调。你不能自己设置它们。要了解这些事件,请覆盖 onCancel(DialogInterface) 和 onDismiss(DialogInterface)。
onDestroyView: 删除对话框。
onDetach:当片段不再附加到其 activity 时调用。这在 onDestroy() 之后调用,除非片段实例在 Activity 重新创建期间保留(请参阅 setRetainInstance(boolean)),在这种情况下它在 onStop() 之后调用。
onDismiss: 当对话框关闭时调用此方法。
onSaveInstanceState:调用以要求片段保存其当前动态状态,以便稍后在其进程重新启动的新实例中重建。如果稍后需要创建片段的新实例,那么您在此处放置在 Bundle 中的数据将在给 onCreate(Bundle)、onCreateView(LayoutInflater, ViewGroup, Bundle) 和 onActivity 的 Bundle 中可用创建(捆绑)。 这对应于 Activity.onSaveInstanceState(Bundle),那里的大部分讨论也适用于此处。但是请注意:这个方法可以在 onDestroy() 之前的任何时候被调用。在很多情况下,一个片段可能大部分都被拆除了(比如当放在返回堆栈上没有 UI 显示时),但它的状态不会被保存,直到它拥有的 activity 实际需要保存它的状态。
onStart:当Fragment对用户可见时调用。这通常与包含 Activity 的生命周期的 Activity.onStart 有关。
onStop:当Fragment不再启动时调用。这通常与包含 Activity 生命周期的 Activity.onStop 有关。
在网上进行了更多搜索后,我现在通过执行以下操作设法触发了一些事件:
在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() 现在会在我旋转屏幕时触发,在关闭对话框片段时也会触发