Xamarin.Android DialogFragment некоторые события LifeCycle не запускаются
У меня проблема с работой 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 не запускается.
Как вы можете видеть на коде,
- OnDismiss
- OnPause
- OnStop
- OnHiddenChanged
- OnDestroyView
- OnDetach
- OnCancel
Никто из них не уволен. Интересно, есть ли у кого-то такая же проблема?
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() теперь запускается при повороте экрана, также при отклонении фрагмента диалога
Ориентация не влияет на жизненный цикл фрагмента диалога.
DialogFragment делает разные вещи, чтобы сохранить жизненный цикл фрагмента, а не Dialog. Обратите внимание, что диалоги, как правило, являются автономными объектами - они представляют собой свое собственное окно, получая свои собственные входные события и часто сами решая, когда исчезнуть (получая событие возврата клавиши или пользователь нажимает кнопку).
DialogFragment должен гарантировать, что то, что происходит с состояниями Fragment и Dialog, остается согласованным. Чтобы сделать это, он следит за тем, чтобы события в диалоге не отображались, и заботится об удалении своего состояния, когда они происходят. Это означает, что вы должны использовать Show(FragmentManager, String) или Show(FragmentTransaction, String), чтобы добавить экземпляр DialogFragment в ваш пользовательский интерфейс, поскольку они отслеживают, как DialogFragment должен удалять себя, когда диалоговое окно закрывается.
Кроме того, знайте, что существуют определенные методы жизненного цикла, которые зависят от какого-либо другого метода, к которому нужно обращаться, например: OnDestroy и OnDestroyView зависят от закрытия или закрытия кнопки "назад" или закрытия фрагмента в каком-либо смысле. Обратите внимание, что при изменении ориентации будут вызываться события жизненного цикла действия, а не фрагмент диалога. Один фрагмент никак не влияет на жизненный цикл другого.
Для получения информации, связанной с работой с жизненными циклами, проверьте это. Этот парень прекрасно проанализировал все аспекты жизненного цикла 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 или ниже, дочерние фрагменты, восстанавливаемые из saveInstanceState, восстанавливаются после возврата onCreate. При нацеливании на N или выше и работе на N или более новой версии платформы они восстанавливаются Fragment.onCreate.
onCreateDialog: переопределить для создания собственного настраиваемого контейнера диалога. Обычно это используется для отображения AlertDialog вместо общего диалога; при этом 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, будут доступны в Bundle, передаваемом onCreate(Bundle), onCreateView(LayoutInflater, ViewGroup, Bundle) и onActivityCreated(Bundle). Это соответствует Activity.onSaveInstanceState(Bundle), и большая часть обсуждения там также применима и здесь. Обратите внимание, однако: этот метод может быть вызван в любое время до onDestroy(). Во многих ситуациях фрагмент может быть в основном разрушен (например, когда он помещен в задний стек без отображения пользовательского интерфейса), но его состояние не будет сохранено до тех пор, пока его собственное действие фактически не должно будет сохранить свое состояние.
onStart: вызывается, когда фрагмент виден пользователю. Обычно это связано с Activity.onStart жизненного цикла, содержащего активность.
onStop: вызывается, когда фрагмент больше не запускается. Обычно это связано с Activity.onStop жизненного цикла, в котором находится активность.