是否可以为整个应用设置一个活动指示器?

时间:2017-08-08 19:58:26

标签: xamarin xamarin.forms

我的应用程序中有活动指标,但我觉得这很重复。我想知道我是否可以定义一个活动指标并在整个应用程序中使用它?

以下是我在应用中拥有的五个活动指标之一的代码。除标签文字更改外,其中每个人都完全相同。

<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>

如果可能的话,哪里最好放置,以便可以从应用程序的任何地方调用它?

编辑:

让一切正常,并用我创建的控件替换所有活动指标。下面是代码,希望这可以帮助将来的某个人。

使用绑定控制xaml

<?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 =&#34; False&#34;不是必需的,因为它在BindableProperty.Create中的默认值为false。通过执行此indicator.IsBusy = true;

,可以从后端代码访问和更改IsBusy
<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>
....

1 个答案:

答案 0 :(得分:1)

这是否涵盖了整个页面?如果是这样你可以使用DependencyService显示/隐藏加载指示器你必须下载这个Android / iOS的NuGet包:AndHUD / BTProgressHUD ,如下所示:

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
    }

}

当你需要展示或隐藏它时,你可以使用:

public static void ShowLoadingIndicator(string progressText = "Loading...")
{
    Device.BeginInvokeOnMainThread(() =>
    {
        DependencyService.Get<IHudService>().ShowHud(progressText);
    });
}

public static void HideLoadingIndicator()
{
    Device.BeginInvokeOnMainThread(() =>
    {
        DependencyService.Get<IHudService>().HideHud();
    });
}

希望这有帮助。