Skip to content

Commit

Permalink
Merge pull request #2229 from DGenix/docs
Browse files Browse the repository at this point in the history
Documentation improvements for ViewModel lifecycle and Android Presenter
  • Loading branch information
martijn00 authored Sep 26, 2017
2 parents fb0280d + abd6e72 commit 1b5f7aa
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,5 @@ public MvxDialogFragmentPresentationAttribute(bool cancelable = true, Type activ
/// Indicates if the dialog can be canceled
/// </summary>
public bool Cancelable { get; set; } = DefaultCancelable;

/// <summary>
/// Indicates if the fragment can be cached. For dialogs it is false by default.
/// </summary>
public new bool IsCacheableFragment { get; set; } = false;
}
}
2 changes: 1 addition & 1 deletion docs/_documentation/fundamentals/navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ The events available are:
* BeforeClose
* AfterClose

You might be using `Init()` or `Start()` methods in your ViewModels when updating from MvvmCross 4.x. This is now deprecated because it was done using reflection and therefor not very safe. With the new navigation a method called `Task Initialize()` will be called. This method is typed and async.
You might be using `Init()` or `Start()` methods in your ViewModels when updating from MvvmCross 4.x. This is now deprecated because it was done using reflection and therefore not very safe. When MvxNavigationService is used, a typed method called `Task Initialize()` will be available for you to perform any async heavy operations.

### Uri navigation

Expand Down
13 changes: 7 additions & 6 deletions docs/_documentation/fundamentals/viewmodel-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ order: 5

Alongside [a new Navigation Service](https://www.mvvmcross.com/documentation/fundamentals/navigation), MvvmCross provides a new lifecycle for ViewModels with many enhancements such as async initialization. The current lifecycle includes:

1. Construction
2. Initialization
1. Construction: Called when the object is instantiated. You can use Dependency Injection here to introduce all dependencies!
2. Prepare: Called before the navigation is done. You can use this method to receive and store all parameters (it is your responsibility to handle them).
3. Initialize: Called right after the navigation is done. This method returns a Task, which means you can mark it as async and use the await safely. If this method fails, the `Navigate` call that you are probably awaiting will fail, so you might want to catch that exception.

Also note that starting from MvvmCross 5.0 ViewModels will be coupled to the lifecycle of the view. This means that the ViewModel has the following methods available:
Also note that starting from MvvmCross 5.0, ViewModels will be coupled to the lifecycle of the view. This means that the ViewModel has the following methods available:

```c#
void ViewCreated();
Expand All @@ -28,11 +29,11 @@ void ViewDisappeared();
void ViewDestroy();
```

The MvxViewController, MvxFragment(s), MvxActivity and the UWP views will call those methods open the platform specific events that are fired. This will give us a more refined control of the ViewModel and the state of its lifecycle. There may be binding that you want to update or resources to clean up, these lifecycle events can help with that.
The MvxViewController, MvxFragment(s), MvxActivity and the UWP views will call those methods when the platform specific events are fired. This will give you a more refined control of the ViewModel and its state. There may be certain bindings that you want to update or resources that you want to clean up in these calls.

It should be noted however that it is not 100% reliable but it should work for most of the apps. We don't know what you do in the lifecycle of your app and what could interfere with the called order of the viewmodel lifecycle events.
However, it should be noted that it is not 100% reliable, due to the natural complex process of any View in different contexts. It _will_ work for most of the apps and most of the cases. But we aware that we don't know what you plan to do in the lifecycle of your app and what whether that could interfere with the called order of the viewmodel lifecycle events.

## Mapping view event to viewmodel events
## Mapping view event to ViewModel events

There has been a thread going on on the [Xamarin forums](https://forums.xamarin.com/discussion/comment/240043/) where the implementation is discussed of this functionality. MvvmCross has based its lifecycle support on this thread and those events.

Expand Down
69 changes: 52 additions & 17 deletions docs/_documentation/presenters/android-view-presenter.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ category: Presenters

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:

- Fragments (Nested)
- Activity's
- Dialogs
- Tabs / ViewPager
- Activities
- Fragments
- Nested Fragments
- Dialog Fragments
- TabLayout / ViewPager

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

- NavigationDrawer
- BottomNavigationBar
- BottomNavigationBar (single backstack)
- BottomSheetDialog
- Master/Detail Flows
- Nested navigation
Expand All @@ -29,27 +30,57 @@ The presenter uses a set of `PresentationAttributes` to define how a view will b

### MvxActivityPresentationAttribute

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

- Extras: Use this `Bundle` to add any extra parameters to the Activity Intent.
- SharedElements: Consists on a `IDictionary<string, View>` that you can use to add shared view elements to the transition. When using the AppCompat version, the string keys are not relevant.

### 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. The framework will then help you setting up the navigation and backstack.

The ViewPresenter supports also 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:

- ActivityHostViewModelType: 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: 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: Resource id where your fragment will be presented.
- AddToBackStack: Default value is `false`. If you set it to `true` the FragmentTransaction will be added to the backstack.
- EnterAnimation: Resource id for the animation that will be run when the fragment is shown.
- ExitAnimation Resource id for the animation that will be run when the fragment is closed.
- PopEnterAnimation: Resource id for the animation that will be run when the fragment comes back to foreground.
- PopExitAnimation: Resource id for the animation that will be run when the fragment is retrieved from foreground.
- TransitionStyle: In case you want to use a Transition Style, use this property by setting its resource id.
- SharedElements: Consists on a `IDictionary<string, View>` that you can use to add shared view elements to the transition. When using the AppCompat version, the string keys are not relevant.
- IsCacheableFragment: 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.

### MvxDialogFragmentPresentationAttribute

Extends `MvxFragmentPresentationAttribute` and shows it in a `Dialog`
This attribute extends `MvxFragmentPresentationAttribute`, which means you can use all the properties it provedes 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:

### MvxFragmentPresentationAttribute
- Cancelable: Default value is `true`. This property indicates if the dialog can be canceled.

### MvxViewPagerFragmentPresentationAttribute (AppCompat only)

Hosted inside an Activity.
This attribute extends `MvxFragmentPresentationAttribute`, which means you can use all the properties it provedes 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:

### MvxTabLayoutPresentationAttribute
- Title: Title for the ViewPager. It will also be used as Title for the TabLayout when using MvxTabLayoutPresentationAttribute.
- ViewPagerResourceId: The resource id for the ViewPager that will be used as host.

Extends `MvxFragmentPresentationAttribute` and puts the Fragment into a ViewPager with TabLayout.
### MvxTabLayoutPresentationAttribute (AppCompat only)

### MvxViewPagerFragmentPresentationAttribute
This attribute extends `MvxViewPagerFragmentPresentationAttribute`, which means you can use all the properties it provedes 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:

Extends `MvxFragmentPresentationAttribute` and puts the Fragment into a ViewPager.
- TabLayoutResourceId: The resource id for the TabLayout that will be used.

## 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.
- 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

Expand All @@ -75,16 +106,20 @@ The presenter is completely extensible! You can override any attribute and custo
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 `MvxAppCompatViewPresenter` and make it the presenter of your application in Setup.cs (by overriding the method `CreatePresenter`).
2. Subclass `MvxAndroidViewPresente` 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:

```c#
_attributeTypesToShowMethodDictionary.Add(
typeof(MyCustomModePresentationAttribute),
(type, attribute, request) => ShowMyCustomModeView(type, (MyCustomPresentationAttribute)attribute, request));
new MvxPresentationAttributeAction
{
ShowAction = (view, attribute, request) => ShowMyCustomModeView(view, (MyCustomPresentationAttribute)attribute, request),
CloseAction = (viewModel, attribute) => CloseMyCustomModeView(viewModel, (MyCustomPresentationAttribute)attribute)
});
```

4. Implement a method that takes care of the presentation mode (in the example above, `ShowMyCustomModeView`).
4. 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`).
5. Use your attribute over a view class. Ready!


Expand Down

0 comments on commit 1b5f7aa

Please sign in to comment.