Skip to content
This repository was archived by the owner on Jun 20, 2023. It is now read-only.

Conversation

@cosminstirbu
Copy link
Contributor

@cosminstirbu cosminstirbu commented Nov 24, 2017

Support Libraries Version (eg: 23.3.0):

26.1.0

Does this change any of the generated binding API's?

It only adds a new binding project for android.arch.lifecycle:extensions:1.0.0

Describe your contribution

As mentioned in #76 - being able to reference the new ViewModelProvider from Architecture Components (which can be found in android.arch.lifecycle:extensions) allows proper handling of the .NET ViewModel's lifecycle in relation to the Activity / Fragment's lifecycle (such as having the ViewModel survive during configuration changes such as screen rotation).

This is an usage example (that leverages MvvmLight):

using System; using Android.Arch.Lifecycle; using GalaSoft.MvvmLight; namespace TestArchitectureComponents.Extensions { public static class ViewModelProvierExtensions { public static T Get<T>(this ViewModelProvider viewModelProvier, Func<T> viewModelFactory) where T : ViewModelBase { var androidViewModelHolder = (AndroidViewModelHolder) viewModelProvier.Get(Java.Lang.Class.FromType(typeof(AndroidViewModelHolder))); return androidViewModelHolder.GetViewModel(viewModelFactory); } } /// Cannot make the class generic due to: Pending exception android.runtime.JavaProxyThrowable: System.NotSupportedException: Constructing instances of generic types from Java is not supported, as the type parameters cannot be determined. class AndroidViewModelHolder : Android.Arch.Lifecycle.ViewModel { private object _viewModel; public T GetViewModel<T>(Func<T> viewModelFactory) where T : ViewModelBase { if (_viewModel == null) { _viewModel = viewModelFactory(); } return _viewModel as T; } } } 

Your MvvmLight ViewModel:

 using System; using GalaSoft.MvvmLight; namespace TestArchitectureComponents.ViewModel { public class MainViewModel : ViewModelBase { public int Random { get; set; } = new Random().Next(); /// <summary> /// Initializes a new instance of the MainViewModel class. /// </summary> public MainViewModel() { } } } 

And your activity:

using System; using Android.App; using Android.OS; using Android.Arch.Lifecycle; using Android.Support.V4.App; using TestArchitectureComponents.Extensions; using TestArchitectureComponents.ViewModel; namespace TestArchitectureComponents { [Activity(Label = "TestArchitectureComponents", MainLauncher = true)] public class MainActivity : FragmentActivity { public int Random { get; set; } = new Random().Next(); protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); var viewModel = ViewModelProviders.Of(this).Get(() => ViewModelLocator.Current.Main); System.Diagnostics.Debug.WriteLine($"Activity random is {Random}, View Model random is: {viewModel.Random}"); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); } } } 

When you'll rotate your screen you'll notice that

System.Diagnostics.Debug.WriteLine($"Activity random is {Random}, View Model random is: {viewModel.Random}"); prints a different number for the Activity - as it gets recreated, but it prints the same number for MainViewModel since it's kept alive during configuration changes.

Please review this thoroughly as I'm coming from an iOS / Android native background development so there are changes that I might have missed some things.

new ArtifactInfo (ARCH_CORE_PKG_NAME, "common", "Xamarin.Android.Arch.Core.Common", "1.0.0", "1.0.0", "1.0.0.0", true) { PathPrefix = "arch-core/" },
new ArtifactInfo (ARCH_LIFECYCLE_PKG_NAME, "common", "Xamarin.Android.Arch.Lifecycle.Common", "1.0.1", "1.0.1", "1.0.1.0", true) { PathPrefix = "arch-lifecycle/" },
new ArtifactInfo (ARCH_LIFECYCLE_PKG_NAME, "runtime", "Xamarin.Android.Arch.Lifecycle.Runtime", "1.0.0", "1.0.0", "1.0.0.0") { PathPrefix = "arch-lifecycle/" },
new ArtifactInfo (ARCH_LIFECYCLE_PKG_NAME, "runtime", "Xamarin.Android.Arch.Lifecycle.Runtime", "1.0.3", "1.0.3", "1.0.3.0") { PathPrefix = "arch-lifecycle/" },
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've bumped android.arch.lifecycle:runtime to 1.0.3

I've also updated all the template.nuspec files that were referencing the previous version.

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<!--
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I didn't do any transformation to the generated bindings.

If there's something in particular you want me to look at - please let me know.

If you want me to clean up the template comments, I can do that.

<Folder Include="Additions\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\support-fragment\source\Fragment.csproj">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if all these projects need to be referenced, or if referencing just the Fragment one should suffice since Fragment also references the projects above.

Changed it from arch-lifecycle\extensions\source\Arch.Lifecycle.Extensions to arch-lifecycle\extensions\source
@xamarin xamarin deleted a comment from dnfclas Dec 12, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

4 participants