Getting-started

Fundamentals

Advanced

Platforms

Plugins

Samples

Tutorials

Upgrading

Contributing

Android View Presenter

Edit

View Presenter Overview

The default presenter for Android named MvxAndroidViewPresenter or MvxAppCompatViewPresenter when using the Android AppCompat support library offers out of the box support for the following navigation patterns / strategies:

  • Activities
  • Fragments
  • Nested Fragments
  • Dialog Fragments
  • TabLayout / ViewPager

Navigation patterns that should be easy to implement with this are:

  • NavigationDrawer
  • BottomNavigationBar (single backstack)
  • BottomSheetDialog
  • Master/Detail Flows
  • Nested navigation

Also if your app needs another kind of presentation mode, you can easily extend it!

Presentation Attributes

The presenter uses a set of PresentationAttributes to define how a view will be displayed. The existing attributes are:

MvxActivityPresentationAttribute

Use this attribute if you want to display an Activity in your application. An Activity will be the root of your application and can also act as a host for fragments. Alongside the attribute, your view can customize the presentation by using these attribute properties:

Name Type Description
Extras Bundle Use this Bundle to add any extra parameters to the Activity Intent.

MvxFragmentPresentationAttribute

A Fragment is hosted inside an Activity (or a fragment). By using this ViewPresenter, you can decide whether to make all of your screens Activities, or to use an Activity host and many Fragments inside of it. MvvmCross can handle both scenarios smoothly.

The ViewPresenter also supports nested fragments in one level: This means you can show fragments inside of a Fragment without extending any code!

Use this attribute over a Fragment view class and customize its presentation by using these properties:

Name Type Description
ActivityHostViewModelType Type The ViewModel type of the Activity that will be the host of your fragment. In case that Activity is not the current one in foreground, the ViewPresenter will show it before showing the fragment. Can be left empty only in case of fragments nesting.
FragmentHostViewType Type The View type of the Fragment that will be the host of your fragment. Use this property only in case you want a fragment to be shown as nested.
FragmentContentId int Resource id where your fragment will be presented.
AddToBackStack bool Default value is false. If you set it to true the FragmentTransaction will be added to the backstack.
EnterAnimation int Resource id for the animation that will be run when the fragment is shown.
ExitAnimation int Resource id for the animation that will be run when the fragment is closed.
PopEnterAnimation int Resource id for the animation that will be run when the fragment comes back to foreground.
PopExitAnimation int Resource id for the animation that will be run when the fragment is retrieved from foreground.
TransitionStyle int In case you want to use a Transition Style, use this property by setting its resource id.
IsCacheableFragment bool Default value is false. You should leave it that way unless you really want/need to reuse a fragment view (for example, in case you are displaying a WebView, you might want to cache the already loaded URL). If it is set to true, the ViewPresenter will try to find a Fragment instance already present in the FragmentManager object before instantiating a new one and will reuse that object.
Tag string Tag to use for the Fragment. The presenter uses this to add fragments to the fragment transactions and to find fragments again later. This is useful to use, if you want to use the same fragment in the same view multiple times. In such cases you would need to provide your own tag for each instance. Defaults to the Java class name of the Fragment.
PopBackStackImmediateName string The name to be passed into PopBackStackImmediate when closing the fragment. Assigning an empty string will default to using the FragmentJavaName. Assigning a null will pop the top fragment when PopBackStackImmediateFlag is set to None.
PopBackStackImmediateFlag MvxPopBackStack Flag to be used with PopBackStackImmediate. None, all entries up to but not including that entry will be removed. Inclusive, all matching entries will be consumed until one that doesn’t match is found or the bottom of the stack is reached.

When providing a value for EnterAnimation you need to provide one for ExitAnimation as well, otherwise the animation won’t work (same applies in the other way around).

Same as above, if you want to set a Pop animation, you will need to set four animation resources: EnterAnimation, ExitAnimation, PopEnterAnimation and PopExitAnimation. Otherwise the animation won’t work.

MvxDialogFragmentPresentationAttribute

This attribute extends MvxFragmentPresentationAttribute, which means you can use all the properties it provides to customize the presentation. Use this attribute over a FragmentDialog view class to display a dialog and take advantage of even more customization with this property:

Name Type Description
Cancelable bool Default value is true. This property indicates if the dialog can be canceled.

MvxViewPagerFragmentPresentationAttribute (AppCompat only)

This attribute extends MvxFragmentPresentationAttribute, which means you can use all the properties it provides to customize the presentation. use this attribute over a Fragment view class to display a fragment inside of a ViewPager and take advantage of even more customization with these properties:

Name Type Description
Title string Title for the ViewPager. It will also be used as Title for the TabLayout when using MvxTabLayoutPresentationAttribute.
ViewPagerResourceId int The resource id for the ViewPager that will be used as host.

Note: If you intend to display your fragment in more than one host activity, please remember to set the property ActivityHostViewModelType on each attribute!

MvxTabLayoutPresentationAttribute (AppCompat only)

This attribute extends MvxViewPagerFragmentPresentationAttribute, which means you can use all the properties it provides to customize the presentation. use this attribute over a Fragment view class to display a fragment inside of a ViewPager with TabLayout and take advantage of even more customization with this property:

Name Type Description
TabLayoutResourceId int The resource id for the TabLayout that will be used.

Note: If you intend to display your fragment in more than one host activity, please remember to set the property ActivityHostViewModelType on each attribute!

Views without attributes: Default values

  • If a view class has no attribute over it, the presenter will check the type and try to create the correct attribute for it:

  • Activity -> MvxActivityPresentationAttribute
  • Fragment -> MvxFragmentPresentationAttribute
  • DialogFragment -> MvxDialogFragmentPresentationAttribute

Override a presentation attribute at runtime

To override a presentation attribute at runtime you can implement the IMvxOverridePresentationAttribute in your view and determine the presentation attribute in the PresentationAttribute method like this:

public MvxBasePresentationAttribute PresentationAttribute(MvxViewModelRequest request)
{
    return new MvxFragmentPresentationAttribute()
    {
        
    };
}

As you can see in the code snippet, you will be able to make your choice using a MvxViewModelRequest. This object will contain the PresentationValues dictionary alongside other properties.

If you return null from the PresentationAttribute method, the ViewPresenter will fallback to the attribute used to decorate the view. If the view is not decorated with any presentation attribute, then it will use the default attribute instead.

Hint: Be aware that this.ViewModel property will be null during PresentationAttribute. If you want to have the ViewModel instance available, you need to use the MvxNavigationService and cast the request parameter to MvxViewModelInstanceRequest.

Shared Element transitions

To add a Shared Element transition navigating to an Activity or Fragment implement the IMvxAndroidSharedElements in your hosting Activity. You can then use FetchSharedElementsToAnimate to assign the view elements you want to transition.

public IDictionary<string, View> FetchSharedElementsToAnimate(MvxBasePresentationAttribute attribute, MvxViewModelRequest request)
{
    IDictionary<string, View> sharedElements = new Dictionary<string, View>();

    if (request.ViewModelType == typeof(SharedElementSecondChildViewModel))
    {
        var selectedLogo = FindViewById<ImageView>(Resource.Id.img_logo);
        sharedElements.Add("identifier", selectedLogo);
    }

    return sharedElements;
}

FetchSharedElementsToAnimate provides access to the MvxViewModelRequest used for the navigation as well as the attributed used by the view navigating to. The dictionary that is returned must contain an identifier as well as the view element to transition.

Hint: Be aware that you must have already specified the transition name on the view elements you add to the dictionary.

The view you are navigating to will receive a Bundle that contains additional metadata. Being the identifier as well as the transition name. MvvmCross provides an extension method to assist with extracting this metadata, GetSharedElementTransitionNames , which can be used to get identifier and transition name pairs.

static IDictionary<string, string> GetSharedElementTransitionNames(this Bundle bundle)

Furthermore, if the identifier you passed through is the Android resource id name or Android resource tag. You can make use of the following extension method to find the corresponding view element and apply the transition name if required.

static void SetSharedElementsByTag(this Bundle bundle, View view)

static void SetSharedElementsById(this Bundle bundle, View view)

You can also check out the Playground Shared Elements sample.

Extensibility

Attributes

The presenter is completely extensible! You can override any attribute and customize attribute members.

You can also define new attributes to satisfy your needs. The steps to do so are:

  1. Add a new attribute that extends MvxBasePresentationAttribute
  2. Subclass MvxAndroidViewPresenter or MvxAppCompatViewPresenter and make it the presenter of your application in Setup.cs (by overriding the method CreatePresenter).
  3. Override the method RegisterAttributeTypes and add a registry to the dictionary like this:
_attributeTypesToShowMethodDictionary.Add(
    typeof(MyCustomModePresentationAttribute),
    new MvxPresentationAttributeAction
    {
        ShowAction = (view, attribute, request) => ShowMyCustomModeView(view, (MyCustomPresentationAttribute)attribute, request),
        CloseAction = (viewModel, attribute) => CloseMyCustomModeView(viewModel, (MyCustomPresentationAttribute)attribute)
    });
  1. Implement a method that takes care of the presentation mode (in the example above, ShowMyCustomModeView) and a method that takes care of a ViewModel closing (in the example above, CloseMyCustomModeView).
  2. Use your attribute over a view class. Ready!

Fragment Lifecycle

To get more control over your Fragment lifecycle (or activity) and transitions, you can override the following methods. You can also modify your fragment transitions :

MvxAndroidViewPresenter

void OnBeforeFragmentChanging(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)

void OnFragmentChanged(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)

void OnFragmentChanging(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)

void OnFragmentPopped(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute)

MvxAppCompatViewPresenter

void OnBeforeFragmentChanging(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)

void OnFragmentChanged(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
        
void OnFragmentChanging(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute, MvxViewModelRequest request)
		
void OnFragmentPopped(FragmentTransaction ft, Fragment fragment, MvxFragmentPresentationAttribute attribute)

Activity Transitions

In case you want to override the transition options bundle pasted between 2 activities you can override the following method :


Bundle CreateActivityTransitionOptions(Intent intent, MvxActivityPresentationAttribute attribute, MvxViewModelRequest request)

Sample please!

You can browse the code of the Playground (Android project) to see this presenter in action.