Browse Source

Merge pull request #7756 from AvaloniaUI/features/android-single-view-lifetime

singleview lifetime for android.
fixes/center-screen-maximized-parent
Dan Walmsley 5 years ago
committed by GitHub
parent
commit
4e9f184db9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      samples/ControlCatalog.Android/MainActivity.cs
  2. 10
      samples/ControlCatalog.Android/SplashActivity.cs
  3. 5
      src/Android/Avalonia.Android/AndroidPlatform.cs
  4. 43
      src/Android/Avalonia.Android/AvaloniaActivity.cs
  5. 7
      src/Android/Avalonia.Android/AvaloniaView.cs
  6. 28
      src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs
  7. 2
      src/iOS/Avalonia.iOS/Platform.cs
  8. 7
      src/iOS/Avalonia.iOS/SingleViewLifetime.cs

10
samples/ControlCatalog.Android/MainActivity.cs

@ -1,18 +1,16 @@
using Android.App; using Android.App;
using Android.OS;
using Android.Content.PM; using Android.Content.PM;
using Avalonia;
using Avalonia.Android; using Avalonia.Android;
namespace ControlCatalog.Android namespace ControlCatalog.Android
{ {
[Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)] [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AvaloniaActivity public class MainActivity : AvaloniaActivity<App>
{ {
protected override void OnCreate(Bundle? savedInstanceState) protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{ {
base.OnCreate(savedInstanceState); return base.CustomizeAppBuilder(builder);
Content = new MainView();
} }
} }
} }

10
samples/ControlCatalog.Android/SplashActivity.cs

@ -1,9 +1,6 @@
using Android.App; using Android.App;
using Android.Content; using Android.Content;
using Android.OS; using Android.OS;
using Application = Android.App.Application;
using Avalonia;
namespace ControlCatalog.Android namespace ControlCatalog.Android
{ {
@ -19,13 +16,6 @@ namespace ControlCatalog.Android
{ {
base.OnResume(); base.OnResume();
if (Avalonia.Application.Current == null)
{
AppBuilder.Configure<App>()
.UseAndroid()
.SetupWithoutStarting();
}
StartActivity(new Intent(Application.Context, typeof(MainActivity))); StartActivity(new Intent(Application.Context, typeof(MainActivity)));
} }
} }

5
src/Android/Avalonia.Android/AndroidPlatform.cs

@ -1,9 +1,9 @@
using System; using System;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Android; using Avalonia.Android;
using Avalonia.Android.Platform; using Avalonia.Android.Platform;
using Avalonia.Android.Platform.Input; using Avalonia.Android.Platform.Input;
using Avalonia.Controls;
using Avalonia.Controls.Platform; using Avalonia.Controls.Platform;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
@ -19,6 +19,7 @@ namespace Avalonia
public static T UseAndroid<T>(this T builder) where T : AppBuilderBase<T>, new() public static T UseAndroid<T>(this T builder) where T : AppBuilderBase<T>, new()
{ {
var options = AvaloniaLocator.Current.GetService<AndroidPlatformOptions>() ?? new AndroidPlatformOptions(); var options = AvaloniaLocator.Current.GetService<AndroidPlatformOptions>() ?? new AndroidPlatformOptions();
return builder return builder
.UseWindowingSubsystem(() => AndroidPlatform.Initialize(options), "Android") .UseWindowingSubsystem(() => AndroidPlatform.Initialize(options), "Android")
.UseSkia(); .UseSkia();

43
src/Android/Avalonia.Android/AvaloniaActivity.cs

@ -1,28 +1,55 @@
using Android.App;
using Android.OS; using Android.OS;
using Android.Views;
using Android.Content.PM;
using AndroidX.AppCompat.App; using AndroidX.AppCompat.App;
using Android.Content.Res; using Android.Content.Res;
using AndroidX.Lifecycle; using AndroidX.Lifecycle;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls;
namespace Avalonia.Android namespace Avalonia.Android
{ {
public abstract class AvaloniaActivity : AppCompatActivity public abstract class AvaloniaActivity<TApp> : AppCompatActivity where TApp : Application, new()
{ {
internal class SingleViewLifetime : ISingleViewApplicationLifetime
{
public AvaloniaView View { get; internal set; }
public Control MainView
{
get => (Control)View.Content;
set => View.Content = value;
}
}
internal AvaloniaView View; internal AvaloniaView View;
internal AvaloniaViewModel _viewModel; internal AvaloniaViewModel _viewModel;
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseAndroid();
protected override void OnCreate(Bundle savedInstanceState) protected override void OnCreate(Bundle savedInstanceState)
{ {
var builder = AppBuilder.Configure<TApp>();
CustomizeAppBuilder(builder);
View = new AvaloniaView(this); View = new AvaloniaView(this);
SetContentView(View); SetContentView(View);
_viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel; var lifetime = new SingleViewLifetime();
lifetime.View = View;
if (_viewModel.Content != null) builder.AfterSetup(x =>
{ {
View.Content = _viewModel.Content; _viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel;
}
if (_viewModel.Content != null)
{
View.Content = _viewModel.Content;
}
View.Prepare();
});
builder.SetupWithLifetime(lifetime);
base.OnCreate(savedInstanceState); base.OnCreate(savedInstanceState);
} }

7
src/Android/Avalonia.Android/AvaloniaView.cs

@ -12,7 +12,7 @@ namespace Avalonia.Android
{ {
public class AvaloniaView : FrameLayout public class AvaloniaView : FrameLayout
{ {
private readonly EmbeddableControlRoot _root; private EmbeddableControlRoot _root;
private readonly ViewImpl _view; private readonly ViewImpl _view;
private IDisposable? _timerSubscription; private IDisposable? _timerSubscription;
@ -21,6 +21,11 @@ namespace Avalonia.Android
{ {
_view = new ViewImpl(context); _view = new ViewImpl(context);
AddView(_view.View); AddView(_view.View);
}
internal void Prepare ()
{
_root = new EmbeddableControlRoot(_view); _root = new EmbeddableControlRoot(_view);
_root.Prepare(); _root.Prepare();
} }

28
src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs

@ -1,6 +1,7 @@
using Foundation;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Foundation;
using UIKit; using UIKit;
namespace Avalonia.iOS namespace Avalonia.iOS
@ -8,6 +9,17 @@ namespace Avalonia.iOS
public class AvaloniaAppDelegate<TApp> : UIResponder, IUIApplicationDelegate public class AvaloniaAppDelegate<TApp> : UIResponder, IUIApplicationDelegate
where TApp : Application, new() where TApp : Application, new()
{ {
class SingleViewLifetime : ISingleViewApplicationLifetime
{
public AvaloniaView View;
public Control MainView
{
get => View.Content;
set => View.Content = value;
}
}
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseiOS(); protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseiOS();
[Export("window")] [Export("window")]
@ -18,7 +30,9 @@ namespace Avalonia.iOS
{ {
var builder = AppBuilder.Configure<TApp>(); var builder = AppBuilder.Configure<TApp>();
CustomizeAppBuilder(builder); CustomizeAppBuilder(builder);
var lifetime = new Lifetime();
var lifetime = new SingleViewLifetime();
builder.AfterSetup(_ => builder.AfterSetup(_ =>
{ {
Window = new UIWindow(); Window = new UIWindow();
@ -35,15 +49,5 @@ namespace Avalonia.iOS
Window.Hidden = false; Window.Hidden = false;
return true; return true;
} }
class Lifetime : ISingleViewApplicationLifetime
{
public AvaloniaView View;
public Control MainView
{
get => View.Content;
set => View.Content = value;
}
}
} }
} }

2
src/iOS/Avalonia.iOS/Platform.cs

@ -45,6 +45,7 @@ namespace Avalonia.iOS
Timer ??= new DisplayLinkTimer(); Timer ??= new DisplayLinkTimer();
var keyboard = new KeyboardDevice(); var keyboard = new KeyboardDevice();
var softKeyboard = new SoftKeyboardHelper(); var softKeyboard = new SoftKeyboardHelper();
AvaloniaLocator.CurrentMutable AvaloniaLocator.CurrentMutable
.Bind<IPlatformOpenGlInterface>().ToConstant(GlFeature) .Bind<IPlatformOpenGlInterface>().ToConstant(GlFeature)
.Bind<ICursorFactory>().ToConstant(new CursorFactoryStub()) .Bind<ICursorFactory>().ToConstant(new CursorFactoryStub())
@ -57,6 +58,7 @@ namespace Avalonia.iOS
.Bind<IRenderTimer>().ToConstant(Timer) .Bind<IRenderTimer>().ToConstant(Timer)
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface()) .Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface())
.Bind<IKeyboardDevice>().ToConstant(keyboard); .Bind<IKeyboardDevice>().ToConstant(keyboard);
keyboard.PropertyChanged += (_, changed) => keyboard.PropertyChanged += (_, changed) =>
{ {
if (changed.PropertyName == nameof(KeyboardDevice.FocusedElement)) if (changed.PropertyName == nameof(KeyboardDevice.FocusedElement))

7
src/iOS/Avalonia.iOS/SingleViewLifetime.cs

@ -1,7 +0,0 @@
namespace Avalonia.iOS
{
public class SingleViewLifetime
{
}
}
Loading…
Cancel
Save