From 1cb0dbee170ab24acc2992595a6d8d6c13a949c2 Mon Sep 17 00:00:00 2001 From: cabauman Date: Sat, 21 Mar 2020 18:07:25 +0900 Subject: [PATCH 1/3] Mark deprecated Fragment classes as obsolete --- src/ReactiveUI/Platforms/android/ReactiveFragment.cs | 2 ++ src/ReactiveUI/Platforms/android/ReactivePreferenceFragment.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/ReactiveUI/Platforms/android/ReactiveFragment.cs b/src/ReactiveUI/Platforms/android/ReactiveFragment.cs index 87a9141c77..4a6b49d6a0 100644 --- a/src/ReactiveUI/Platforms/android/ReactiveFragment.cs +++ b/src/ReactiveUI/Platforms/android/ReactiveFragment.cs @@ -20,6 +20,7 @@ namespace ReactiveUI /// /// The view model type. [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")] + [Obsolete("This class was deprecated in API level 28. Use the ReactiveFragment in ReactiveUI.AndroidX (recommended) or ReactiveUI.AndroidSupport for consistent behavior across all devices and access to Lifecycle.", false)] public class ReactiveFragment : ReactiveFragment, IViewFor, ICanActivate where TViewModel : class { @@ -62,6 +63,7 @@ object IViewFor.ViewModel /// (i.e. you can call RaiseAndSetIfChanged). /// [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")] + [Obsolete("This class was deprecated in API level 28. Use the ReactiveFragment in ReactiveUI.AndroidX (recommended) or ReactiveUI.AndroidSupport for consistent behavior across all devices and access to Lifecycle.", false)] public class ReactiveFragment : Fragment, IReactiveNotifyPropertyChanged, IReactiveObject, IHandleObservableErrors { private readonly Subject _activated = new Subject(); diff --git a/src/ReactiveUI/Platforms/android/ReactivePreferenceFragment.cs b/src/ReactiveUI/Platforms/android/ReactivePreferenceFragment.cs index 1c1e220cab..3c3fb94b57 100644 --- a/src/ReactiveUI/Platforms/android/ReactivePreferenceFragment.cs +++ b/src/ReactiveUI/Platforms/android/ReactivePreferenceFragment.cs @@ -20,6 +20,7 @@ namespace ReactiveUI /// /// The view model type. [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")] + [Obsolete("This class was deprecated in API level 28. Use the ReactivePreferenceFragment in ReactiveUI.AndroidX (recommended) or ReactiveUI.AndroidSupport for consistent behavior across all devices and access to Lifecycle.", false)] public class ReactivePreferenceFragment : ReactivePreferenceFragment, IViewFor, ICanActivate where TViewModel : class { @@ -62,6 +63,7 @@ object IViewFor.ViewModel /// (i.e. you can call RaiseAndSetIfChanged). /// [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")] + [Obsolete("This class was deprecated in API level 28. Use the ReactivePreferenceFragment in ReactiveUI.AndroidX (recommended) or ReactiveUI.AndroidSupport for consistent behavior across all devices and access to Lifecycle.", false)] public class ReactivePreferenceFragment : PreferenceFragment, IReactiveNotifyPropertyChanged, IReactiveObject, IHandleObservableErrors { private readonly Subject _activated = new Subject(); From 6436eba33114df4a1b313e0539335299d1e6aa06 Mon Sep 17 00:00:00 2001 From: cabauman Date: Sat, 21 Mar 2020 18:08:21 +0900 Subject: [PATCH 2/3] Add PreferenceFragment to AndroidX and Support --- .../ReactivePreferenceFragment.cs | 153 ++++++++++++++++++ .../ReactiveUI.AndroidSupport.csproj | 1 + .../ReactivePreferenceFragment.cs | 153 ++++++++++++++++++ .../ReactiveUI.AndroidX.csproj | 1 + 4 files changed, 308 insertions(+) create mode 100644 src/ReactiveUI.AndroidSupport/ReactivePreferenceFragment.cs create mode 100644 src/ReactiveUI.AndroidX/ReactivePreferenceFragment.cs diff --git a/src/ReactiveUI.AndroidSupport/ReactivePreferenceFragment.cs b/src/ReactiveUI.AndroidSupport/ReactivePreferenceFragment.cs new file mode 100644 index 0000000000..987c5d2f24 --- /dev/null +++ b/src/ReactiveUI.AndroidSupport/ReactivePreferenceFragment.cs @@ -0,0 +1,153 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Reactive; +using System.Reactive.Linq; +using System.Reactive.Subjects; +using Android.Runtime; +using Android.Support.V7.Preferences; + +namespace ReactiveUI.AndroidSupport +{ + /// + /// This is a PreferenceFragment that is both an Activity and has ReactiveObject powers + /// (i.e. you can call RaiseAndSetIfChanged). + /// + /// The view model type. + [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")] + public abstract class ReactivePreferenceFragment : ReactivePreferenceFragment, IViewFor, ICanActivate + where TViewModel : class + { + private TViewModel _viewModel; + + /// + /// Initializes a new instance of the class. + /// + protected ReactivePreferenceFragment() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The handle. + /// The ownership. + protected ReactivePreferenceFragment(IntPtr handle, JniHandleOwnership ownership) + : base(handle, ownership) + { + } + + /// + public TViewModel ViewModel + { + get => _viewModel; + set => this.RaiseAndSetIfChanged(ref _viewModel, value); + } + + /// + object IViewFor.ViewModel + { + get => _viewModel; + set => _viewModel = (TViewModel)value; + } + } + + /// + /// This is a PreferenceFragment that is both an Activity and has ReactiveObject powers + /// (i.e. you can call RaiseAndSetIfChanged). + /// + [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")] + public abstract class ReactivePreferenceFragment : PreferenceFragmentCompat, IReactiveNotifyPropertyChanged, IReactiveObject, IHandleObservableErrors + { + private readonly Subject _activated = new Subject(); + private readonly Subject _deactivated = new Subject(); + + /// + /// Initializes a new instance of the class. + /// + protected ReactivePreferenceFragment() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The handle. + /// The ownership. + protected ReactivePreferenceFragment(IntPtr handle, JniHandleOwnership ownership) + : base(handle, ownership) + { + } + + /// + public event PropertyChangingEventHandler PropertyChanging; + + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + public IObservable> Changing => this.GetChangingObservable(); + + /// + public IObservable> Changed => this.GetChangedObservable(); + + /// + public IObservable ThrownExceptions => this.GetThrownExceptionsObservable(); + + /// + /// Gets a signal when the fragment is activated. + /// + public IObservable Activated => _activated.AsObservable(); + + /// + /// Gets a signal when the fragment is deactivated. + /// + public IObservable Deactivated => _deactivated.AsObservable(); + + /// + public IDisposable SuppressChangeNotifications() => IReactiveObjectExtensions.SuppressChangeNotifications(this); + + /// + void IReactiveObject.RaisePropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + + /// + void IReactiveObject.RaisePropertyChanging(PropertyChangingEventArgs args) + { + PropertyChanging?.Invoke(this, args); + } + + /// + public override void OnPause() + { + base.OnPause(); + _deactivated.OnNext(Unit.Default); + } + + /// + public override void OnResume() + { + base.OnResume(); + _activated.OnNext(Unit.Default); + } + + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + _activated?.Dispose(); + _deactivated?.Dispose(); + } + + base.Dispose(disposing); + } + } +} diff --git a/src/ReactiveUI.AndroidSupport/ReactiveUI.AndroidSupport.csproj b/src/ReactiveUI.AndroidSupport/ReactiveUI.AndroidSupport.csproj index 63dd57066e..4a7f6ab8ae 100644 --- a/src/ReactiveUI.AndroidSupport/ReactiveUI.AndroidSupport.csproj +++ b/src/ReactiveUI.AndroidSupport/ReactiveUI.AndroidSupport.csproj @@ -12,6 +12,7 @@ + diff --git a/src/ReactiveUI.AndroidX/ReactivePreferenceFragment.cs b/src/ReactiveUI.AndroidX/ReactivePreferenceFragment.cs new file mode 100644 index 0000000000..051fcd7b2d --- /dev/null +++ b/src/ReactiveUI.AndroidX/ReactivePreferenceFragment.cs @@ -0,0 +1,153 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.Reactive; +using System.Reactive.Linq; +using System.Reactive.Subjects; +using Android.Runtime; +using AndroidX.Preference; + +namespace ReactiveUI.AndroidX +{ + /// + /// This is a PreferenceFragment that is both an Activity and has ReactiveObject powers + /// (i.e. you can call RaiseAndSetIfChanged). + /// + /// The view model type. + [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")] + public abstract class ReactivePreferenceFragment : ReactivePreferenceFragment, IViewFor, ICanActivate + where TViewModel : class + { + private TViewModel _viewModel; + + /// + /// Initializes a new instance of the class. + /// + protected ReactivePreferenceFragment() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The handle. + /// The ownership. + protected ReactivePreferenceFragment(IntPtr handle, JniHandleOwnership ownership) + : base(handle, ownership) + { + } + + /// + public TViewModel ViewModel + { + get => _viewModel; + set => this.RaiseAndSetIfChanged(ref _viewModel, value); + } + + /// + object IViewFor.ViewModel + { + get => _viewModel; + set => _viewModel = (TViewModel)value; + } + } + + /// + /// This is a PreferenceFragment that is both an Activity and has ReactiveObject powers + /// (i.e. you can call RaiseAndSetIfChanged). + /// + [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")] + public abstract class ReactivePreferenceFragment : PreferenceFragmentCompat, IReactiveNotifyPropertyChanged, IReactiveObject, IHandleObservableErrors + { + private readonly Subject _activated = new Subject(); + private readonly Subject _deactivated = new Subject(); + + /// + /// Initializes a new instance of the class. + /// + protected ReactivePreferenceFragment() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The handle. + /// The ownership. + protected ReactivePreferenceFragment(IntPtr handle, JniHandleOwnership ownership) + : base(handle, ownership) + { + } + + /// + public event PropertyChangingEventHandler PropertyChanging; + + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + public IObservable> Changing => this.GetChangingObservable(); + + /// + public IObservable> Changed => this.GetChangedObservable(); + + /// + public IObservable ThrownExceptions => this.GetThrownExceptionsObservable(); + + /// + /// Gets a signal when the fragment is activated. + /// + public IObservable Activated => _activated.AsObservable(); + + /// + /// Gets a signal when the fragment is deactivated. + /// + public IObservable Deactivated => _deactivated.AsObservable(); + + /// + public IDisposable SuppressChangeNotifications() => IReactiveObjectExtensions.SuppressChangeNotifications(this); + + /// + void IReactiveObject.RaisePropertyChanged(PropertyChangedEventArgs args) + { + PropertyChanged?.Invoke(this, args); + } + + /// + void IReactiveObject.RaisePropertyChanging(PropertyChangingEventArgs args) + { + PropertyChanging?.Invoke(this, args); + } + + /// + public override void OnPause() + { + base.OnPause(); + _deactivated.OnNext(Unit.Default); + } + + /// + public override void OnResume() + { + base.OnResume(); + _activated.OnNext(Unit.Default); + } + + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + _activated?.Dispose(); + _deactivated?.Dispose(); + } + + base.Dispose(disposing); + } + } +} diff --git a/src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj b/src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj index 3afde54707..ba31b17526 100644 --- a/src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj +++ b/src/ReactiveUI.AndroidX/ReactiveUI.AndroidX.csproj @@ -12,6 +12,7 @@ + From 3f987c6d6c97d19bf0cc72d42b3ce6c62bbd33b9 Mon Sep 17 00:00:00 2001 From: cabauman Date: Sat, 21 Mar 2020 18:09:27 +0900 Subject: [PATCH 3/3] Housekeeping - Use readonly keyword where applicable. - Remove unused usings. --- .../ReactiveFragment.cs | 18 ------------------ .../ReactiveFragmentActivity.cs | 14 -------------- .../ReactivePagerAdapter.cs | 4 +--- .../ReactiveRecyclerViewAdapter.cs | 7 +------ .../ReactivePagerAdapter.cs | 4 +--- .../ReactiveRecyclerViewAdapter.cs | 4 +--- 6 files changed, 4 insertions(+), 47 deletions(-) diff --git a/src/ReactiveUI.AndroidSupport/ReactiveFragment.cs b/src/ReactiveUI.AndroidSupport/ReactiveFragment.cs index c74f8b67c4..f06525cd0b 100644 --- a/src/ReactiveUI.AndroidSupport/ReactiveFragment.cs +++ b/src/ReactiveUI.AndroidSupport/ReactiveFragment.cs @@ -4,29 +4,11 @@ // See the LICENSE file in the project root for full license information. using System; -using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; -using System.Linq; using System.Reactive; -using System.Reactive.Concurrency; -using System.Reactive.Disposables; using System.Reactive.Linq; using System.Reactive.Subjects; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.Serialization; -using System.Text; -using System.Threading; -using Android.App; -using Android.Content; -using Android.OS; -using Android.Runtime; -using Android.Util; -using Android.Views; -using Android.Widget; -using Splat; namespace ReactiveUI.AndroidSupport { diff --git a/src/ReactiveUI.AndroidSupport/ReactiveFragmentActivity.cs b/src/ReactiveUI.AndroidSupport/ReactiveFragmentActivity.cs index d41b15b168..0bfdf52464 100644 --- a/src/ReactiveUI.AndroidSupport/ReactiveFragmentActivity.cs +++ b/src/ReactiveUI.AndroidSupport/ReactiveFragmentActivity.cs @@ -4,31 +4,17 @@ // See the LICENSE file in the project root for full license information. using System; -using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Contracts; using System.Linq; using System.Reactive; -using System.Reactive.Concurrency; -using System.Reactive.Disposables; using System.Reactive.Linq; using System.Reactive.Subjects; using System.Reactive.Threading.Tasks; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.Serialization; -using System.Text; -using System.Threading; using System.Threading.Tasks; using Android.App; using Android.Content; -using Android.OS; -using Android.Runtime; using Android.Support.V4.App; -using Android.Views; -using Android.Widget; -using Splat; namespace ReactiveUI.AndroidSupport { diff --git a/src/ReactiveUI.AndroidSupport/ReactivePagerAdapter.cs b/src/ReactiveUI.AndroidSupport/ReactivePagerAdapter.cs index 1d94372810..f0a1326491 100644 --- a/src/ReactiveUI.AndroidSupport/ReactivePagerAdapter.cs +++ b/src/ReactiveUI.AndroidSupport/ReactivePagerAdapter.cs @@ -8,8 +8,6 @@ using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Reactive.Disposables; -using System.Threading; using Android.Support.V4.View; using Android.Views; using DynamicData; @@ -31,7 +29,7 @@ public class ReactivePagerAdapter : PagerAdapter, IEnableLogger private readonly SourceList _list; private readonly Func _viewCreator; private readonly Action _viewInitializer; - private IDisposable _inner; + private readonly IDisposable _inner; /// /// Initializes a new instance of the class. diff --git a/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs b/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs index f445d9787f..e8c4e20bef 100644 --- a/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs +++ b/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs @@ -6,14 +6,9 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; -using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Reactive.Disposables; using System.Reactive.Linq; -using System.Reflection; -using System.Runtime.Serialization; -using System.Threading; using Android.Support.V7.Widget; using Android.Views; using DynamicData; @@ -33,7 +28,7 @@ public abstract class ReactiveRecyclerViewAdapter : RecyclerView.Ada { private readonly ISourceList _list; - private IDisposable _inner; + private readonly IDisposable _inner; /// /// Initializes a new instance of the class. diff --git a/src/ReactiveUI.AndroidX/ReactivePagerAdapter.cs b/src/ReactiveUI.AndroidX/ReactivePagerAdapter.cs index b294292044..9b554daf9e 100644 --- a/src/ReactiveUI.AndroidX/ReactivePagerAdapter.cs +++ b/src/ReactiveUI.AndroidX/ReactivePagerAdapter.cs @@ -8,8 +8,6 @@ using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Reactive.Disposables; -using System.Threading; using Android.Views; using AndroidX.ViewPager.Widget; using DynamicData; @@ -31,7 +29,7 @@ public class ReactivePagerAdapter : PagerAdapter, IEnableLogger private readonly SourceList _list; private readonly Func _viewCreator; private readonly Action _viewInitializer; - private IDisposable _inner; + private readonly IDisposable _inner; /// /// Initializes a new instance of the class. diff --git a/src/ReactiveUI.AndroidX/ReactiveRecyclerViewAdapter.cs b/src/ReactiveUI.AndroidX/ReactiveRecyclerViewAdapter.cs index 7504a5a7ac..da7064785f 100644 --- a/src/ReactiveUI.AndroidX/ReactiveRecyclerViewAdapter.cs +++ b/src/ReactiveUI.AndroidX/ReactiveRecyclerViewAdapter.cs @@ -8,8 +8,6 @@ using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Reactive.Disposables; -using System.Threading; using AndroidX.RecyclerView.Widget; using DynamicData; using DynamicData.Binding; @@ -26,7 +24,7 @@ public abstract class ReactiveRecyclerViewAdapter : RecyclerView.Ada { private readonly ISourceList _list; - private IDisposable _inner; + private readonly IDisposable _inner; /// /// Initializes a new instance of the class.