Фрагмент первой вкладки MvvmCross был создан и уничтожен при загрузке окна просмотра с помощью навигационной системы <> - PullRequest
0 голосов
/ 19 сентября 2018

Я использую Mvvmcross 6 с Xamarin Android.Только что обновлен до Mvx 6.2, но проблема остается той же.Я следую за образцом Playground, чтобы загрузить viewpager.У меня есть активность, удерживая просмотр на 3 вкладки.В модели представления для деятельности вкладки добавляются в панель просмотра:

    var tasks = new List<Task>();
    tasks.Add(_navigationService.Navigate<SettingPreferenceViewModel>());
    tasks.Add(_navigationService.Navigate<SettingTrackingViewModel>());
    tasks.Add(_navigationService.Navigate<SettingCalorieViewModel>());
    await Task.WhenAll(tasks);

В примере игровой площадки фрагменты вкладок не будут создаваться при построении панели просмотра путем перехода к модели просмотра этих вкладок.Фрагменты будут создаваться только при их отображении.

Однако в моем случае после Navigate () будет создан SettingPreferenceFragment.После создания второй вкладки с помощью Navigate (), SettingPreferenceFragment будет уничтожен.Позже, SettingPreferenceFragment был создан снова, когда он отображается.Т.е. первая вкладка была создана дважды.Первое создание и уничтожение являются неожиданными.

Для моих второй и третьей вкладок коды в основном такие же, как и на первой.Ни у одного из них нет такой же проблемы, как у Tab One.Фрагменты не будут созданы после перехода к соответствующей модели представления.

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

Спасибо,

Ник

SettingRootViewModel.cs

public SettingRootViewModel(
    IMvxNavigationService navigationService
    //IMvxMessenger messenger
)
{
    _navigationService = navigationService;

    ShowInitialViewModelsCommand = new MvxAsyncCommand(ShowInitialViewModels);
}


public IMvxAsyncCommand ShowInitialViewModelsCommand { get; private set; }

private async Task ShowInitialViewModels()
{
    var tasks = new List<Task>();
    tasks.Add(_navigationService.Navigate<SettingPreferenceViewModel>());
    tasks.Add(_navigationService.Navigate<SettingTrackingViewModel>());
    tasks.Add(_navigationService.Navigate<SettingCalorieViewModel>());
    await Task.WhenAll(tasks);
}

SettingActivity.cs

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

            SetContentView(Resource.Layout.activity_setting);

           …..

            ViewModel.ShowInitialViewModelsCommand.Execute();
        }

Activity.xml

  ……
  <LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
      android:id="@+id/tabs_fragment_setting_viewpager"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      local:tabIndicatorColor="@color/gray_700"
      local:tabGravity="fill"
      local:tabMode="fixed" />

    <android.support.v4.view.ViewPager
      android:id="@+id/viewpager_fragment_setting_viewpager"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>

  </LinearLayout>

SettingPreferenceFragment

BaseFragment - это MvxFragment.Я попытался реализовать с MvxFragment напрямую, но ситуация остается той же.

    [MvxTabLayoutPresentation(TabLayoutResourceId = Resource.Id.tabs_fragment_setting_viewpager, 
    ViewPagerResourceId = Resource.Id.viewpager_fragment_setting_viewpager, 
    Title = "P", 
    ActivityHostViewModelType = typeof(SettingRootViewModel))]
[Register(nameof(SettingPreferenceFragment))]

    public class SettingPreferenceFragment : BaseFragment<SettingPreferenceViewModel>
    {
        protected override int FragmentId => Resource.Layout.fragment_setting_preference;


        public override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
        }

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container,
                                          Bundle savedInstanceState)
        {
            // view = BindingInflate(Resource.Layout.fragment_route_summary, null) is handled in base fragment
            var view = base.OnCreateView(inflater, container, savedInstanceState);

            return view;
        }

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

1 Ответ

0 голосов
/ 08 июня 2019

У меня была точно такая же проблема, и я думаю, что мне удалось решить ее по крайней мере для моего случая.(Я нахожусь на MvvmCross 6.2.3)

Я вызывал ShowInitialViewModelsCommand из обратного вызова жизненного цикла ViewMpel ViewAppearing (см. https://www.mvvmcross.com/documentation/fundamentals/viewmodel-lifecycle),, потому что мне показалось неправильным, что Фрагменту пришлось беспокоиться о навигации.Когда я обнаружил эту проблему, я переместил ее обратно в OnCreate, как в примере Playground, и проблема исчезла. После дальнейших экспериментов похоже, что я могу вызвать ее из обратного вызова ViewMrel ViewCreated, который вызывается раньше, чем ViewAppearing.

Исходя из этого, моя теория заключается в том, что в инициализации ViewPager есть некоторый момент, когда он создает свой первый фрагмент, если он еще не существует, и если этот момент происходит до того, как вы выполняете вызовы Navigate,Фрагмент будет создан дважды. Вы выполняете большую работу в вашем OnCreate, может быть?

Но это всего лишь теория, конечно. В любом случае, это работает, может быть, это кому-то поможет.

...