This is how you can show different layouts for items in a RecyclerView
Posted by Sven-Michael Stübe on June 12, 2016
There is a old tutorial from Stuart Lodge (Polymorphic lists in the MvvmCross tutorials) where he explains how to show different table cells for different types of ViewModels. This post will show you how to do the same with a MvxRecyclerView. The example code is available on github.
Problem
Sometimes there is the need to layout the items of RecyclerView differently. This is mostly the case, if your ItemsSource stores items of different classes.
ViewModels
For this example, we use the following ViewModels:
Solution
Luckily MvvmCorss includes a neat mechanism for this since version 4.1.5. It’s called TemplateSelector and defined in the interface IMvxTemplateSelector. The purpose of this interface is to map your item to a layout id based on a rule that you can define.
Selecting by ViewModel type
In this scenario, we want to show different layouts for cats (CatViewModel) and fishes (FishViewModel).
Therefore we create a lookup table _typeMapping and use it in GetItemViewType that is called for each item of the list. The parameter forItemObject is the current item for which we should return the view type. We return the layout id directly, because we have one layout id per view type. If you want to know more about the purpose of view types have a look at: Adapter.getItemViewType(int).
Selecting by a property value
In our second scenario we want to show different layouts for old, adult and young pets using the Age property. We have a common base class and there is a generic base class MvxTemplateSelector<T> that allows us to implement IMvxTemplateSelector without casting manually.
This time we override SelectItemViewType that is called with a PetViewModelBase as parameter. We return the layout id directly as view type again. You can use the MvxTemplateSelector<T> in the first scenario, too.
Setting the Selector
You can set the selector in your code behind:
And you can set it in the xml. But this code is not as refactoring safe as the code behind version and you can’t initialize the selector if you create a configurable one. The attribute is called MvxTemplateSelector and has to be set with the full qualified class name of the selector followed by the assembly name.
It is possible to exchange the selector at the runtime as well. The items will update immediately. In the sample the two buttons Type and Age are switching between our two custom selectors. Just give it a try.