Icône de chargement pour l'écran de layout Xamarin Android
-
21-12-2019 - |
Question
Je veux savoir s'il y a de bonnes idées / tutoriels sur la manière d'ajouter le gif de chargement à une mise en page Android lors du traitement survenant et lorsqu'une mise en page de page navigue vers une autre mise en page.
J'ai essayé d'utiliser ceci - andhud
Mais il semble que cela ne fonctionne pas bien avec les bibliothèques de classe de portail (PCL) et les services à l'intérieur du PCL.Je n'ai pas pu trouver beaucoup d'exemples avec ce composant.
Je vois Android utilise une boîte de dialogue de progression pour cela, mais j'espérais une version Xamarin en C # ou tout autre moyen intelligent de le faire.
La solution
Ajouter andhud au projet Android et BTProgresshud à votre projet iOS.
Ensuite, il vous suffit de créer une interface dans la PCL comme ceci:
public enum MaskType
{
None = 1,
Clear,
Black,
Gradient
}
public interface IHudService
{
void Show(string message, MaskType maskType, int progress = -1);
void Dismiss();
void ShowToast(string message, bool showToastCentered = true, double timeoutMs = 1000);
void ShowToast(string message, MaskType maskType, bool showToastCentered = true, double timeoutMs = 1000);
}
et implémentations concrètes dans chacun des projets (exemple IOS):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BigTed;
using Foundation;
using MyExample.Services;
using UIKit;
[assembly: Xamarin.Forms.Dependency(typeof(MyExample.iOS.Services.HudService))]
namespace MyExample.iOS.Services
{
public class HudService : IHudService
{
public HudService()
{
}
#region IHudService Members
public void Show(string message, MaskType maskType, int progress)
{
float p = (float)progress / 100f;
BTProgressHUD.Show(message, p, (ProgressHUD.MaskType)maskType);
}
public void Dismiss()
{
BTProgressHUD.Dismiss();
}
public void ShowToast(string message, bool showToastCentered = true, double timeoutMs = 1000)
{
BTProgressHUD.ShowToast(message, showToastCentered, timeoutMs);
}
public void ShowToast(string message, MaskType maskType, bool showToastCentered = true, double timeoutMs = 1000)
{
BTProgressHUD.ShowToast(message, (ProgressHUD.MaskType)maskType, showToastCentered, timeoutMs);
}
#endregion
}
}
et sur Android:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AndroidHUD;
using MyExample.Services;
using Xamarin.Forms;
using XHUD;
[assembly: Xamarin.Forms.Dependency(typeof(MyExample.Android.Services.HudService))]
namespace MyExample.Android.Services
{
public class HudService : IHudService
{
//Although, not well documented, for Xamarin.Forms, "Forms.Context" is the current activity
public HudService()
{
}
#region IHudService Members
public void Show(string message, MyExample.Services.MaskType maskType, int progress)
{
AndHUD.Shared.Show(Forms.Context, message, progress, (AndroidHUD.MaskType)maskType);
}
public void Dismiss()
{
AndHUD.Shared.Dismiss(Forms.Context);
}
public void ShowToast(string message, bool showToastCentered = true, double timeoutMs = 1000)
{
AndHUD.Shared.ShowToast(Forms.Context, message, (AndroidHUD.MaskType)MyExample.Services.MaskType.Black, TimeSpan.FromSeconds(timeoutMs / 1000), showToastCentered);
}
public void ShowToast(string message, MyExample.Services.MaskType maskType, bool showToastCentered = true, double timeoutMs = 1000)
{
AndHUD.Shared.ShowToast(Forms.Context, message, (AndroidHUD.MaskType)maskType, TimeSpan.FromSeconds(timeoutMs / 1000), showToastCentered);
}
#endregion
}
}
Ceci est essentiellement juste une copie de la façade XHUD.HUD ajoutée aux deux bibliothèques pour lisser les différences d'API.
Ensuite, enregistrez votre service au point d'entrée pour les projets spécifiques à la plate-forme (dans ce cas, appdelegate.cs) et appelez-le de la PCL.Dans mon cas, j'utilise Xamarin.Forms.Labs afin que votre méthode de l'enregistrement peut varier.
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
SetupIocContainer();
Forms.Init();
FormsMaps.Init();
window = new UIWindow(UIScreen.MainScreen.Bounds);
window.RootViewController = App.GetMainPage().CreateViewController();
window.MakeKeyAndVisible();
return true;
}
private void SetupIocContainer()
{
var resolverContainer = new SimpleContainer();
var app = new XFormsAppiOS();
app.Init(this);
resolverContainer.Register<IDevice>(t => AppleDevice.CurrentDevice)
.Register<IDisplay>(t => t.Resolve<IDevice>().Display)
//EDIT: this does not seem necessary after all and actually
//causes it to crash on Android (but works on iOS)
//not sure why
//.Register<IHudService>(t => t.Resolve<IHudService>())
.Register<IXFormsApp>(app)
.Register<IDependencyContainer>(t => resolverContainer);
Resolver.SetResolver(resolverContainer.GetResolver());
}
Dans la PCL, vous pouvez l'instancier et faire quelque chose comme ceci:
private IHudService hudService;
public IHudService HudService
{
get
{
if(hudService == null)
{
hudService = DependencyService.Get<IHudService>();
}
return this.hudService;
}
}
private async Task Setup()
{
this.HudService.Show("Long operation occurring", MaskType.Black);
await Operation();
this.HudService.Dismiss();
}