I am trying to implement tabs through MvvmCross in Xamarin. I came across MvxTabActivity in Android and MvxTabBarViewController in IOS. Both are working well. The problem is MvxTabActivity is obselete. Are there any alternatives for MvxTabActivity?
I found another way to implement this, which uses TabLayout and a ViewPager. The solution asks to use fragments within a fragment. I have pasted the code for this approach. The problem here is on swiping the tabs, all the data in previous tabs is lost. I tried using RetainInstance = true, that gave following exception : "Can't retain fragements that are nested in other fragments."
Product Detail Activity :
[Activity(Label = "ProductDetailView")]
public class ProductDetailView : MvxAppCompatActivity<ProductDetailViewModel>
{
private FrameLayout _mainFrame;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.product_detail_view);
if (FindViewById<FrameLayout>(Resource.Id.frame_Detail) != null)
{
var frag = new NutritionCategoryView();
frag.ViewModel = ViewModel.NutritionCategoryModel;
var trans = SupportFragmentManager.BeginTransaction();
trans.Replace(Resource.Id.frame_Detail, frag);
trans.AddToBackStack(null);
trans.Commit();
}
}
}
Nutrition Category View Fragment :
public class NutritionCategoryView : MvxFragment
{
public NutritionCategoryViewModel vm
{
get { return (NutritionCategoryViewModel) ViewModel; }
}
private TabLayout _tablayout;
private ViewPager _viewPager;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
this.EnsureBindingContextIsSet(inflater);
var view = this.BindingInflate(Resource.Layout.nutrition_category_view, container, false);
SetViewPager(view);
return view;
}
private void SetViewPager(View view)
{
_viewPager = view.FindViewById<Android.Support.V4.View.ViewPager>(Resource.Id.viewpager);
if (_viewPager != null)
{
var fragments = new List<CategoryTabsAdapter.FragmentInfo>
{
new CategoryTabsAdapter.FragmentInfo
{
FragmentType = typeof(CategoryView),
Title = "Proximates",
ViewModel = vm.Category1
},
new CategoryTabsAdapter.FragmentInfo
{
FragmentType = typeof(CategoryView),
Title = "Minerals",
ViewModel = vm.Category2
},
new CategoryTabsAdapter.FragmentInfo
{
FragmentType = typeof(CategoryView),
Title = "Fats",
ViewModel = vm.Category3
},
new CategoryTabsAdapter.FragmentInfo
{
FragmentType = typeof(CategoryView),
Title = "Vitamins",
ViewModel = vm.Category4
}
};
_viewPager.Adapter = new CategoryTabsAdapter(Activity, ChildFragmentManager, fragments);
}
_tablayout = view.FindViewById<TabLayout>(Resource.Id.sliding_tabs);
_tablayout.SetBackgroundColor(Android.Graphics.Color.Black);
_tablayout.SetupWithViewPager(_viewPager);
}
}
Category Tabs Adapter :
public class CategoryTabsAdapter : FragmentStatePagerAdapter
{
private readonly Context _context;
public IEnumerable<FragmentInfo> Fragments { get; private set; }
public CategoryTabsAdapter(Context context, FragmentManager fragmentManager, IEnumerable<FragmentInfo> fragments) : base(fragmentManager)
{
_context = context;
Fragments = fragments;
}
public override int Count
{
get { return Fragments.Count(); }
}
public override Fragment GetItem(int position)
{
var fragmentInfo = Fragments.ElementAt(position);
var fragment = Fragment.Instantiate(_context, Java.Lang.Class.FromType(fragmentInfo.FragmentType).Name);
((MvxFragment)fragment).ViewModel = fragmentInfo.ViewModel;
return fragment;
}
public override ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String(Fragments.ElementAt(position).Title);
}
public class FragmentInfo
{
public string Title { get; set; }
public Type FragmentType { get; set; }
public IMvxViewModel ViewModel { get; set; }
}
}
Category View Fragment
public class CategoryView : MvxFragment<CategoryViewModel>
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
this.EnsureBindingContextIsSet(inflater);
var view = this.BindingInflate(Resource.Layout.category_view, container, false);
//Exception caused here :
//RetainInstance = true;
return view;
}
}
I am new to Xamarin and MvvmCross, so could come up with this much research only. Any solution for either approaches would be of great help.
P.S. This is my first question on Stackoverflow.