Prepare( ... ) method of ViewModel not invoked when using MvxCachingFragmentStatePagerAdapter
Steps to reproduce :scroll:
- 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);
- the
MvxViewPagerFragmentInfodeclarations 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
};
}
}
- The ViewModel is declared as
IMvxViewModel<ActivityIdParameter>and has an implementation forpublic 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
I am also facing the same issue, with view pager with multiple fragments.
I also have encounter this issue.
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 would you be able to submit a PR fixing this issue?
@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).