maui-linux/Xamarin.Forms.Platform.Android/FormsApplicationActivity.cs

277 строки
7.6 KiB
C#

using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Linq;
using Android.App;
using Android.Content;
using Android.Content.Res;
using Android.OS;
using Android.Views;
using Android.Widget;
using Xamarin.Forms.PlatformConfiguration.AndroidSpecific;
using Xamarin.Forms.Internals;
namespace Xamarin.Forms.Platform.Android
{
public class FormsApplicationActivity : Activity, IDeviceInfoProvider
{
public delegate bool BackButtonPressedEventHandler(object sender, EventArgs e);
Application _application;
Platform _canvas;
AndroidApplicationLifecycleState _currentState;
LinearLayout _layout;
AndroidApplicationLifecycleState _previousState;
protected FormsApplicationActivity()
{
_previousState = AndroidApplicationLifecycleState.Uninitialized;
_currentState = AndroidApplicationLifecycleState.Uninitialized;
PopupManager.Subscribe(this);
}
public event EventHandler ConfigurationChanged;
public static event BackButtonPressedEventHandler BackPressed;
public override void OnBackPressed()
{
if (BackPressed != null && BackPressed(this, EventArgs.Empty))
return;
base.OnBackPressed();
}
public override void OnConfigurationChanged(Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
EventHandler handler = ConfigurationChanged;
if (handler != null)
handler(this, new EventArgs());
}
// FIXME: THIS SHOULD NOT BE MANDATORY
// or
// This should be specified in an interface and formalized, perhaps even provide a stock AndroidActivity users
// can derive from to avoid having to do any work.
public override bool OnOptionsItemSelected(IMenuItem item)
{
if (item.ItemId == global::Android.Resource.Id.Home)
_canvas.SendHomeClicked();
return base.OnOptionsItemSelected(item);
}
public override bool OnPrepareOptionsMenu(IMenu menu)
{
_canvas.PrepareMenu(menu);
return base.OnPrepareOptionsMenu(menu);
}
[Obsolete("SetPage is obsolete as of version 1.3.0. Please use protected LoadApplication (Application app) instead.")]
public void SetPage(Page page)
{
var application = new DefaultApplication { MainPage = page };
LoadApplication(application);
}
protected void LoadApplication(Application application)
{
if (application == null)
throw new ArgumentNullException("application");
(application as IApplicationController)?.SetAppIndexingProvider(new AndroidAppIndexProvider(this));
_application = application;
Xamarin.Forms.Application.SetCurrentApplication(application);
SetSoftInputMode();
application.PropertyChanged += AppOnPropertyChanged;
if (application?.MainPage != null)
{
var iver = Platform.GetRenderer(application.MainPage);
if (iver != null) {
iver.Dispose();
application.MainPage.ClearValue(Platform.RendererProperty);
}
}
SetMainPage();
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
ActivityResultCallbackRegistry.InvokeCallback(requestCode, resultCode, data);
}
protected override void OnCreate(Bundle savedInstanceState)
{
Window.RequestFeature(WindowFeatures.IndeterminateProgress);
base.OnCreate(savedInstanceState);
_layout = new LinearLayout(BaseContext);
SetContentView(_layout);
Xamarin.Forms.Application.ClearCurrent();
_previousState = _currentState;
_currentState = AndroidApplicationLifecycleState.OnCreate;
OnStateChanged();
}
protected override void OnDestroy()
{
// may never be called
base.OnDestroy();
PopupManager.Unsubscribe(this);
if (_canvas != null)
((IDisposable)_canvas).Dispose();
}
protected override void OnPause()
{
_layout.HideKeyboard(true);
// Stop animations or other ongoing actions that could consume CPU
// Commit unsaved changes, build only if users expect such changes to be permanently saved when thy leave such as a draft email
// Release system resources, such as broadcast receivers, handles to sensors (like GPS), or any resources that may affect battery life when your activity is paused.
// Avoid writing to permanent storage and CPU intensive tasks
base.OnPause();
_previousState = _currentState;
_currentState = AndroidApplicationLifecycleState.OnPause;
OnStateChanged();
}
protected override void OnRestart()
{
base.OnRestart();
_previousState = _currentState;
_currentState = AndroidApplicationLifecycleState.OnRestart;
OnStateChanged();
}
protected override void OnResume()
{
// counterpart to OnPause
base.OnResume();
_previousState = _currentState;
_currentState = AndroidApplicationLifecycleState.OnResume;
OnStateChanged();
}
protected override void OnStart()
{
base.OnStart();
_previousState = _currentState;
_currentState = AndroidApplicationLifecycleState.OnStart;
OnStateChanged();
}
// Scenarios that stop and restart you app
// -- Switches from your app to another app, activity restarts when clicking on the app again.
// -- Action in your app that starts a new Activity, the current activity is stopped and the second is created, pressing back restarts the activity
// -- The user recieves a phone call while using your app on his or her phone
protected override void OnStop()
{
// writing to storage happens here!
// full UI obstruction
// users focus in another activity
// perform heavy load shutdown operations
// clean up resources
// clean up everything that may leak memory
base.OnStop();
_previousState = _currentState;
_currentState = AndroidApplicationLifecycleState.OnStop;
OnStateChanged();
}
void AppOnPropertyChanged(object sender, PropertyChangedEventArgs args)
{
if (args.PropertyName == "MainPage")
InternalSetPage(_application.MainPage);
if (args.PropertyName == PlatformConfiguration.AndroidSpecific.Application.WindowSoftInputModeAdjustProperty.PropertyName)
SetSoftInputMode();
}
void InternalSetPage(Page page)
{
if (!Forms.IsInitialized)
throw new InvalidOperationException("Call Forms.Init (Activity, Bundle) before this");
if (_canvas != null)
{
_canvas.SetPage(page);
return;
}
PopupManager.ResetBusyCount(this);
_canvas = new Platform(this);
if (_application != null)
_application.Platform = _canvas;
_canvas.SetPage(page);
_layout.AddView(_canvas.GetViewGroup());
}
async void OnStateChanged()
{
if (_application == null)
return;
if (_previousState == AndroidApplicationLifecycleState.OnCreate && _currentState == AndroidApplicationLifecycleState.OnStart)
_application.SendStart();
else if (_previousState == AndroidApplicationLifecycleState.OnStop && _currentState == AndroidApplicationLifecycleState.OnRestart)
_application.SendResume();
else if (_previousState == AndroidApplicationLifecycleState.OnPause && _currentState == AndroidApplicationLifecycleState.OnStop)
await _application.SendSleepAsync();
}
void SetMainPage()
{
InternalSetPage(_application.MainPage);
}
void SetSoftInputMode()
{
SoftInput adjust = SoftInput.AdjustPan;
if (Xamarin.Forms.Application.Current != null)
{
var elementValue = Xamarin.Forms.Application.Current.OnThisPlatform().GetWindowSoftInputModeAdjust();
switch (elementValue)
{
default:
case WindowSoftInputModeAdjust.Pan:
adjust = SoftInput.AdjustPan;
break;
case WindowSoftInputModeAdjust.Resize:
adjust = SoftInput.AdjustResize;
break;
}
}
Window.SetSoftInputMode(adjust);
}
internal class DefaultApplication : Application
{
}
}
}