Created
April 17, 2015 07:32
-
-
Save jorisvergeer/d91dafa19cdc2a407608 to your computer and use it in GitHub Desktop.
ReactiveUI RoutedViewHost for Xamarin-Android
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reactive.Linq; | |
using Android.App; | |
using ReactiveUI; | |
namespace ReactiveUI | |
{ | |
class RoutedViewHost : ReactiveObject | |
{ | |
RoutingState _router; | |
public RoutingState Router | |
{ | |
get { return _router; } | |
set { this.RaiseAndSetIfChanged(ref _router, value); } | |
} | |
IObservable<string> _viewContractObservable; | |
public IObservable<string> ViewContractObservable | |
{ | |
get { return _viewContractObservable; } | |
set { this.RaiseAndSetIfChanged(ref _viewContractObservable, value); } | |
} | |
Fragment _defaultContent; | |
public Fragment DefaultContent | |
{ | |
get { return _defaultContent; } | |
set { this.RaiseAndSetIfChanged(ref _defaultContent, value); } | |
} | |
public IViewLocator ViewLocator { get; set; } | |
public RoutedViewHost(FragmentManager fragmentManager, int containerId) | |
{ | |
Fragment viewLastAdded = null; | |
ViewContractObservable = Observable.Return(default(string)); | |
var vmAndContract = this.WhenAnyObservable(x => x.Router.CurrentViewModel) | |
.CombineLatest(this.WhenAnyObservable(x => x.ViewContractObservable), | |
(vm, contract) => new { ViewModel = vm, Contract = contract, }); | |
vmAndContract.Subscribe(x => | |
{ | |
if (viewLastAdded != null) | |
fragmentManager.BeginTransaction().Remove(viewLastAdded).Commit(); | |
if (x.ViewModel == null) | |
{ | |
if (DefaultContent != null) | |
{ | |
fragmentManager.BeginTransaction().Add(containerId, DefaultContent).Commit(); | |
} | |
return; | |
} | |
var viewLocator = ViewLocator ?? ReactiveUI.ViewLocator.Current; | |
var view = viewLocator.ResolveView(x.ViewModel, x.Contract) ?? viewLocator.ResolveView(x.ViewModel); | |
view.ViewModel = x.ViewModel; | |
var added = view as Fragment; | |
if (added != null) | |
{ | |
viewLastAdded = added; | |
} | |
else | |
{ | |
throw new Exception(String.Format("'{0}' must be a Fragment", view.GetType().FullName)); | |
} | |
fragmentManager.BeginTransaction().Add(containerId, viewLastAdded).Commit(); | |
}, RxApp.DefaultExceptionHandler.OnNext); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment