MvvmCross icon indicating copy to clipboard operation
MvvmCross copied to clipboard

Prepare( ... ) method of ViewModel not invoked when using MvxCachingFragmentStatePagerAdapter

Open rikbosch opened this issue 7 years ago • 5 comments

Steps to reproduce :scroll:

  1. Define an activity with a tablayout:
  var viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
            if (viewPager != null)
            {
                var fragments = new List<MvxViewPagerFragmentInfo>
                {                 
                    new MvxViewPagerFragmentInfo(
                        ViewModel.TextSource.GetText("tab_vehicle"),
                        typeof(PlanningVehicleFragment),
                        typeof(PlanningVehicleViewModel),
                        (ActivityIdParameter) ViewModel.ActivityId),
                    new MvxViewPagerFragmentInfo(
                        ViewModel.TextSource.GetText("tab_driver"),
                        typeof(PlanningDriverFragment),
                        typeof(PlanningDriverViewModel),
                        (ActivityIdParameter) ViewModel.ActivityId)                 
                };

                viewPager.Adapter = new MvxCachingFragmentStatePagerAdapter(this, SupportFragmentManager, fragments);
            }
            var tabLayout = FindViewById<TabLayout>(Resource.Id.tabs);
            tabLayout.SetupWithViewPager(viewPager);
  1. the MvxViewPagerFragmentInfo declarations contain a single parameter of type ActivityIdParameter, which is defined as:
public sealed class ActivityIdParameter
    {
        public Guid ActivityId { get; set; }

        // User-defined conversion from Digit to double
        public static implicit operator Guid(ActivityIdParameter parameter)
        {
            return parameter.ActivityId;
        }
        //  User-defined conversion from double to Digit
        public static implicit operator ActivityIdParameter(Guid id)
        {
            return new ActivityIdParameter
            {
                ActivityId = id
            };
        }
    }
  1. The ViewModel is declared as IMvxViewModel<ActivityIdParameter> and has an implementation for public void Prepare(ActivityIdParameter id)

Expected behavior :thinking:

The Prepare(ActivityIdParameter id) method is called with the provided parameter.

Actual behavior :bug:

The Prepare(ActivityIdParameter id) method is not called

Version: 6.0.0

Platform:

  • [ ] :iphone: iOS
  • [x] :robot: Android
  • [ ] :checkered_flag: WPF
  • [ ] :earth_americas: UWP
  • [ ] :apple: MacOS
  • [ ] :tv: tvOS
  • [ ] :monkey: Xamarin.Forms

rikbosch avatar Apr 20 '18 10:04 rikbosch

I am also facing the same issue, with view pager with multiple fragments.

gvsharma avatar Apr 30 '18 11:04 gvsharma

I also have encounter this issue.

DrQwertySilence avatar May 09 '18 21:05 DrQwertySilence

The solution in our case was using one of the constructor overloads of MvxViewPagerFragmentInfo that takes an instance of the ViewModel. Doing this, you can build the view model using the generic LoadViewModel method that takes a typed parameter and calls Prepare<T>

Example:

var request = new MvxViewModelInstanceRequest(typeof(ViewModel1));
var parameter = new ViewModel1.Parameters { Prop = propValue };
var viewModel1 = _modelLoader.LoadViewModel(request, parameter, null) as ViewModel1;
var fragInfo = new MvxViewPagerFragmentInfo(viewModel.ViewName,
                                    _viewsContainer.GetViewType(viewModel1.GetType()), viewModel1);

Class MvxCachingFragmentStatePagerAdapter is not prepared to call the generic view model loader method so it calls the Prepare override that takes no parameters when constructing the view model.

claudioredi avatar Jul 25 '18 18:07 claudioredi

@claudioredi would you be able to submit a PR fixing this issue?

nickrandolph avatar Aug 09 '18 05:08 nickrandolph

@nickrandolph: I tried to fix the code but at first sight the change was not as small as I would have expected, abandoned the idea provided there is a valid and easy workaround (the code I pasted on my answer).

claudioredi avatar Aug 09 '18 11:08 claudioredi