Представление фрагмента, связанное со старым экземпляром модели представления при вращении (Android - MVVMCross) - PullRequest
0 голосов
/ 21 сентября 2018

В моем приложении есть активность, и MvxFragment должен быть загружен по умолчанию.Во фрагменте есть кнопка, при нажатии на которую появляется MvxDialogFragment.Когда я нажимаю Да в диалоговом окне, текст должен быть обновлен во фрагменте.

Когда всплывает диалоговое окно и , если я поворачиваюсь и затем нажимаю «Да» , текст не обновляется во фрагменте.

Я загружаю MvxFragmentв методе ViewAppeared () метода ViewModel.Ниже приведен фрагмент:

Модель представления активности:

 public class FirstViewModel
    : MvxViewModel
{
    public FirstViewModel()
    {
        Console.WriteLine("Firstviewmodel : Ctor()");
    }

    public override void ViewAppeared()
    {
        Console.WriteLine("Firstviewmodel : ViewAppeared()");
        Mvx.Resolve<IMvxNavigationService>().Navigate<FragmentAViewModel>();

        base.ViewAppeared();
    }
    public override void ViewCreated()
    {
        Console.WriteLine("Firstviewmodel : ViewCreated()");

        base.ViewCreated();
    }
    public override void ViewAppearing()
    {
        Console.WriteLine("Firstviewmodel : ViewAppearing()");
        base.ViewAppearing();
    }

Файл макета активности:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:id="@+id/toolbar_layout">
    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar"
        local:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
    android:id="@+id/content_frame"
    android:background="#FFFFFF"
    android:layout_below="@id/toolbar_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Макет фрагмента:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#008080">
<TextView
    android:layout_width="match_parent"
    android:layout_height="50dp"
    local:MvxBind="Text FragmentAText" />
<Button
    android:layout_width="match_parent"
    android:text="Click"
    android:layout_height="35dp"
    local:MvxBind="Click ShowDialogCommand" />
</LinearLayout>

Файл фрагмента (.cs):

 [MvxFragmentPresentationAttribute(typeof(FirstViewModel), 
  Resource.Id.content_frame)]
[Register("androidMVVMTest.droid.views.fragmentA")]

public class FragmentAView :MvvmCross.Droid.Support.V4.MvxFragment
{
    public FragmentAViewModel Model
    {
        get
        {
            return (FragmentAViewModel)ViewModel;
        }
    }
    public override void OnCreate(Bundle savedInstanceState)
    {
        Console.WriteLine("Fragment A : OnCreate()");
        RetainInstance = true;
        base.OnCreate(savedInstanceState);
    }

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

        Console.WriteLine("Fragment A : OnCreateView()");
        base.OnCreateView(inflater, container, savedInstanceState);
        return this.BindingInflate(Resource.Layout.FragmentA, null);
    }

FragmentViewModel:

 public class FragmentAViewModel:MvxViewModel
{
    public Action ShowDialog;
    private string _fragmentAText;
    public string FragmentAText
    {
        get
        {
            return _fragmentAText;
        }
        set
        {
            _fragmentAText = value;
            RaisePropertyChanged(() => FragmentAText);
        }
    }
    public FragmentAViewModel()
    {
        Console.WriteLine("FragmentAViewModel : Ctor()");
    }
     public IMvxCommand ShowDialogCommand
    {
        get
        {

            return new MvxCommand(() =>
            {

                  Mvx.Resolve<IMvxNavigationService>().Navigate<DialogViewModel,Dictionary<string,object>>(PrepareDialogNavigationParams(ChangeName));
            });
        }
    }
    private Dictionary<string, object> PrepareDialogNavigationParams(Action operationType)
    {
        Dictionary<string, object> dialogNavigationParams = new Dictionary<string, object>();
        dialogNavigationParams.Add("operation", operationType);
        return dialogNavigationParams;
    }
    private void ChangeName()
    {
        FragmentAText = "Hello!!!";
    }

DialogFragmentViewModel:

 public class DialogViewModel : MvxViewModel<Dictionary<string,object>>
{
    public Action RequestedOperation;

    public IMvxCommand ExecuteYesCommand
    {
        get
        {
            return new MvxCommand(() =>
            {
                RequestedOperation?.Invoke();
                MvvmCross.Platform.Mvx.Resolve<IMvxNavigationService>().Close(this);
            }
            );
        }
    }

   public override void Prepare(Dictionary<string, object> parameter)
    {
        RequestedOperation = parameter["operation"] as Action;
    }
}

Предположим, что текст вфрагмент обновляется в постоянном хранилище.Чтобы при вращении его можно было извлечь из этого .

При вращении создается новый экземпляр модели представления фрагмента.Это может быть связано с загрузкой фрагмента с использованием службы навигации в методе ViewAppeared () FirstViewModel.Тем не менее, я дал RetainInstance = true в FragmentA.cs.

Поскольку RetainInstance имеет значение true, присутствует только один экземпляр представления фрагмента, но при повороте имеется 2 экземпляра модели представления фрагмента.

Мои запросы:

  1. К какому экземпляру viewmodel привязан фрагмент?
  2. Как избежать нескольких экземпляров viewmodel (при вращении) и загрузитьфрагмент по умолчанию в активности?
...