是否可以为整个应用程序设置一个活动指示器? [英] Is it possible to have one Activity indicator for entire app?
问题描述
我的整个应用程序都有活动指示器,但我发现这种情况是重复的.我想知道是否可以定义单个活动指示器并在整个应用中使用它?
I have activity indicators throughout my app but I find this repetitive. I would like to know if I can define a single activity indicator and use it throughout the app?
以下是我在应用程序中拥有的五个活动指标之一的代码.除了标签文字发生变化外,每个人都完全相同.
Below is code of one of five activity indicators that I have in the app. Everyone of them are exactly the same except for the label text changing.
<AbsoluteLayout x:Name="ActivityInd" IsVisible="False" BackgroundColor="Black" Opacity=".75" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<StackLayout AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1" VerticalOptions="Center" HorizontalOptions="Center">
<ActivityIndicator x:Name="Activityblocker" Color="White"/>
<Label Text="Processing Request" TextColor="White"/>
</StackLayout>
</AbsoluteLayout>
如果可能,最好将其放置在哪里,以便可以从应用程序的任何位置调用它?
If it is possible, where would be best to place so it can be called from anywhere in the app?
一切正常,并用我创建的控件替换了所有活动指示器.下面是代码,希望这可以帮助将来的人.
Got everything working and replaced all the activity indicators with the control I created. Below is the code, hopefully this can help someone in the future.
使用绑定控制 xaml
Control xaml with bindings
<?xml version="1.0" encoding="UTF-8"?>
<AbsoluteLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Myapp.ActivityBlocker"
x:Name="ActivityIndAL" IsVisible="{Binding IsBusy, Source={x:Reference ActivityIndAL}}" BackgroundColor="Black" Opacity=".75" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<StackLayout AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1" VerticalOptions="Center" HorizontalOptions="Center">
<ActivityIndicator x:Name="Activityblocker" Color="White" IsEnabled="{Binding IsBusy, Source={x:Reference ActivityIndAL}}" IsRunning="{Binding IsBusy, Source={x:Reference ActivityIndAL}}"/>
<Label Text="{Binding Text, Source={x:Reference ActivityIndAL}}" x:Name="ActivityIndLabel" TextColor="White"/>
</StackLayout>
</AbsoluteLayout>
控制 xaml.cs
public partial class ActivityBlocker : AbsoluteLayout
{
public ActivityBlocker()
{
InitializeComponent();
}
public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(ActivityBlocker));
public static readonly BindableProperty Running = BindableProperty.Create(nameof(IsBusy), typeof(bool), typeof(ActivityBlocker), false);
public string Text
{
get
{
return (string)GetValue(TextProperty);
}
set
{
SetValue(TextProperty, value);
}
}
public bool IsBusy
{
get
{
return (bool)GetValue(Running);
}
set
{
SetValue(Running, value);
}
}
}
如何使用控件:您将xmlns:control="clr-namespace:MyApp"
添加到要使用控件的内容页面.现在添加控件和文本.注意:IsBusy="False" 不是必需的,因为它在 BindableProperty.Create
中的默认值为 false.可以通过执行此操作从后端代码访问和更改 IsBusy indicator.IsBusy = true;
How to use the control: You will add xmlns:control="clr-namespace:MyApp"
to the contentpage of where you want to use the control. Now add the control and the text. Note: IsBusy="False" is not required because it's default value is false in BindableProperty.Create
. IsBusy can be accessed and changed from backend code by doing this indicator.IsBusy = true;
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:control="clr-namespace:MyApp"
....
<ContentPage.Content>
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<control:ActivityBlocker x:Name="indicator" Text="Processing Request" IsBusy="False"/>
</AbsoluteLayout>
</ContentPage.Content>
....
推荐答案
这是否覆盖了整个页面?如果是这样,您可以使用 DependencyService 来显示/隐藏加载指示器您必须下载适用于 Android/iOS 的 NuGet 包:AndHUD/BTProgressHUD,如下所示:
Is this covering the whole page? if that is so you can use a DependencyService to Show/Hide a loading indicator You will have to download this NuGet packages for Android/iOS: AndHUD/BTProgressHUD like this:
using XXXX.Helpers;
namespace XXXX
{
public interface IHudService
{
/// <summary>
/// Shows hud in the secreen
/// </summary>
/// <param name="ProgressText">Set progress</param>
void ShowHud(string ProgressText = StaticData.Loading);
/// <summary>
/// Hides hud.
/// </summary>
void HideHud();
/// <summary>
/// Set text.
/// </summary>
/// <param name="Text">Set text to hub.</param>
void SetText(string Text);
/// <summary>
/// Set progress.
/// </summary>
/// <param name="Progress">Set progress.</param>
/// <param name="ProgressText">Set Text.</param>
void SetProgress(double Progress, string ProgressText = "");
}
}
安卓:
using AndroidHUD;
using Android.Views;
using Xamarin.Forms;
using XXXX.Droid;
using XXXX.DependencyServices;
using XXXX.Helpers;
[assembly: Dependency(typeof(DroidHudService))]
namespace XXXX.Droid
{
public class DroidHudService : IHudService
{
#region IHudManager implementation
bool isHudVisible;
public void ShowHud(string ProgressText = StaticData.Loading)
{
Device.BeginInvokeOnMainThread(() =>
{
AndHUD.Shared.Show(Forms.Context, ProgressText, maskType: MaskType.Black);
isHudVisible = true;
});
}
public void HideHud()
{
Device.BeginInvokeOnMainThread(() =>
{
AndHUD.Shared.Dismiss(Forms.Context);
isHudVisible = false;
});
}
public void SetProgress(double Progress, string ProgressText = "")
{
if (!isHudVisible)
return;
Device.BeginInvokeOnMainThread(() =>
{
int progress = (int)(Progress * 100);
AndHUD.Shared.Show(Forms.Context, ProgressText + progress + "%", progress, MaskType.Black);
});
}
public void SetText(string Text)
{
if (!isHudVisible)
return;
Device.BeginInvokeOnMainThread(() =>
{
AndHUD.Shared.Show(Forms.Context, Text, maskType: MaskType.Black);
});
}
Android.Views.View CustomLoadingView(string ProgressText)
{
Android.Views.View loadingView = new Android.Views.View(Forms.Context);
return loadingView;
}
#endregion
}
}
iOS
using System;
using BigTed;
using CoreAnimation;
using CoreGraphics;
using XXXX.DependencyServices;
using XXXX.Helpers;
using XXXX.iOS;
using Foundation;
using UIKit;
using Xamarin.Forms;
[assembly: Dependency(typeof(IosHudService))]
namespace XXXX.iOS
{
/// <summary>
/// Manages loading indicators in the app.
/// </summary>
public class IosHudService : IHudService
{
UIView _load;
bool isHudVisible;
#region IHudManager implementation
/// <summary>
/// Show loading indicator.
/// </summary>
/// <param name="ProgressText">Progress to set.</param>
public void ShowHud(string ProgressText = StaticData.Loading)
{
isHudVisible = true;
SetText(ProgressText);
}
/// <summary>
/// Hide loading indicator.
/// </summary>
public void HideHud()
{
Device.BeginInvokeOnMainThread(() =>
{
BTProgressHUD.Dismiss();
if (_load != null)
_load.Hidden = true;
isHudVisible = false;
});
}
/// <summary>
/// Method to change Progress Text and show custom loader with Challenge Logo
/// </summary>
/// <param name="ProgressText">Progress text.</param>
public void SetProgress(double Progress, string ProgressText = "")
{
int progress = (int)(Progress * 100);
string text = ProgressText + progress + "%";
SetText(text);
}
/// <summary>
/// Set text to loading indicator.
/// </summary>
/// <param name="text">Text to display.</param>
public void SetText(string text)
{
if (!isHudVisible)
return;
Device.BeginInvokeOnMainThread(() =>
{
BTProgressHUD.Show(status: text, maskType: ProgressHUD.MaskType.Black);
try
{
//if (_load == null) {
// _load = CustomLoadingView (text);
// ProgressHUD.Shared.AddSubview (_load);
//}
lblTitle.Text = text;
UIView[] subView = ProgressHUD.Shared.Subviews;
for (int i = 0; i < subView.Length; i++)
{
subView[i].Hidden = true;
}
_load.Hidden = false;
ProgressHUD.Shared.BringSubviewToFront(_load);
}
catch (Exception ex)
{
#if DEBUG
Console.WriteLine("IosHudService.cs - SetText() " + ex.Message);
#endif
}
});
}
UILabel lblTitle;
/// <summary>
/// Customs the loading view.
/// </summary>
/// <returns>The loading view.</returns>
/// <param name="ProgressText">Progress text.</param>
UIView CustomLoadingView(string ProgressText)
{
UIView loadingView = new UIView();
loadingView.Frame = new CGRect(0, 0, UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height);
UIImageView imgBg = new UIImageView();
imgBg.Image = UIImage.FromFile("load_bg.png");
imgBg.Frame = new CGRect((loadingView.Frame.Width / 2) - 65, (loadingView.Frame.Height / 2) - 70, 130, 140);
loadingView.Add(imgBg);
UIImageView someImageView = new UIImageView();
someImageView.Frame = new CGRect((loadingView.Frame.Width / 2) - 40, (loadingView.Frame.Height / 2) - 50, 75, 75);
someImageView.AnimationImages = new UIImage[]
{
UIImage.FromBundle("spinner.png"),
};
someImageView.AnimationRepeatCount = nint.MaxValue; // Repeat forever.
someImageView.AnimationDuration = 1.0; // Every 1s.
someImageView.StartAnimating();
CABasicAnimation rotationAnimation = new CABasicAnimation();
rotationAnimation.KeyPath = "transform.rotation.z";
rotationAnimation.To = new NSNumber(Math.PI * 2);
rotationAnimation.Duration = 1;
rotationAnimation.Cumulative = true;
rotationAnimation.RepeatCount = float.PositiveInfinity;
someImageView.Layer.AddAnimation(rotationAnimation, "rotationAnimation");
loadingView.Add(someImageView);
lblTitle = new UILabel();
lblTitle.Text = ProgressText;
lblTitle.Frame = new CGRect(imgBg.Frame.X, someImageView.Frame.Y + someImageView.Frame.Height + 15, 130, 20);
lblTitle.TextAlignment = UITextAlignment.Center;
lblTitle.TextColor = UIColor.White;
lblTitle.AdjustsFontSizeToFitWidth = true;
loadingView.Add(lblTitle);
return loadingView;
}
#endregion
}
}
当您需要显示或隐藏它时,您可以使用:
And when ever you need to show it or hide it you can use:
public static void ShowLoadingIndicator(string progressText = "Loading...")
{
Device.BeginInvokeOnMainThread(() =>
{
DependencyService.Get<IHudService>().ShowHud(progressText);
});
}
public static void HideLoadingIndicator()
{
Device.BeginInvokeOnMainThread(() =>
{
DependencyService.Get<IHudService>().HideHud();
});
}
希望这会有所帮助.
这篇关于是否可以为整个应用程序设置一个活动指示器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!