是否可以为整个应用程序设置一个活动指示器? [英] Is it possible to have one Activity indicator for entire app?

查看:30
本文介绍了是否可以为整个应用程序设置一个活动指示器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的整个应用程序都有活动指示器,但我发现这种情况是重复的.我想知道是否可以定义单个活动指示器并在整个应用中使用它?

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆