You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需XAML用户控件的Xamarin Forms快速加载Spinner方案求推荐

可行方案推荐

方案一:基于DependencyService实现原生加载指示器

这种方式直接调用各平台原生加载控件,无需在XAML中添加任何元素,性能更贴近原生,能避开第三方库的性能损耗。

1. 定义共享接口

在共享项目中创建统一接口:

public interface ILoadingIndicatorService
{
    void ShowLoading(string message = "加载中...");
    void HideLoading();
}

2. 各平台实现

Android平台

[assembly: Dependency(typeof(AndroidLoadingIndicatorService))]
namespace YourApp.Droid.Services
{
    public class AndroidLoadingIndicatorService : ILoadingIndicatorService
    {
        private ProgressDialog _progressDialog;

        public void ShowLoading(string message)
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                _progressDialog = new ProgressDialog(Android.App.Application.Context);
                _progressDialog.SetMessage(message);
                _progressDialog.SetCancelable(false);
                _progressDialog.Show();
            });
        }

        public void HideLoading()
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                _progressDialog?.Dismiss();
                _progressDialog = null;
            });
        }
    }
}

iOS平台

[assembly: Dependency(typeof(IosLoadingIndicatorService))]
namespace YourApp.iOS.Services
{
    public class IosLoadingIndicatorService : ILoadingIndicatorService
    {
        private UIActivityIndicatorView _indicator;
        private UIView _overlay;

        public void ShowLoading(string message)
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                var window = UIApplication.SharedApplication.KeyWindow;
                _overlay = new UIView(window.Bounds)
                {
                    BackgroundColor = UIColor.Black.ColorWithAlpha(0.5f),
                    AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
                };

                _indicator = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.Large)
                {
                    Center = _overlay.Center,
                    AutoresizingMask = UIViewAutoresizing.FlexibleLeftMargin | UIViewAutoresizing.FlexibleRightMargin |
                                      UIViewAutoresizing.FlexibleTopMargin | UIViewAutoresizing.FlexibleBottomMargin
                };
                _indicator.StartAnimating();

                _overlay.AddSubview(_indicator);
                window.AddSubview(_overlay);
            });
        }

        public void HideLoading()
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                _indicator?.StopAnimating();
                _overlay?.RemoveFromSuperview();
                _indicator = null;
                _overlay = null;
            });
        }
    }
}

UWP平台

[assembly: Dependency(typeof(UwpLoadingIndicatorService))]
namespace YourApp.UWP.Services
{
    public class UwpLoadingIndicatorService : ILoadingIndicatorService
    {
        private ContentDialog _loadingDialog;

        public void ShowLoading(string message)
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                _loadingDialog = new ContentDialog
                {
                    Title = "",
                    Content = new StackPanel
                    {
                        Orientation = Orientation.Horizontal,
                        Children =
                        {
                            new ProgressRing { IsActive = true, Width = 24, Height = 24, Margin = new Thickness(0,0,10,0) },
                            new TextBlock { Text = message }
                        }
                    },
                    CloseButtonText = "",
                    IsSecondaryButtonEnabled = false,
                    IsPrimaryButtonEnabled = false,
                    FullSizeDesired = false
                };
                _loadingDialog.ShowAsync();
            });
        }

        public void HideLoading()
        {
            MainThread.BeginInvokeOnMainThread(async () =>
            {
                if (_loadingDialog != null)
                {
                    await _loadingDialog.HideAsync();
                    _loadingDialog = null;
                }
            });
        }
    }
}

3. 全局调用封装

在共享项目中封装静态类简化调用:

public static class LoadingManager
{
    private static readonly ILoadingIndicatorService _service = DependencyService.Get<ILoadingIndicatorService>();

    public static void Show(string message = "加载中...") => _service.ShowLoading(message);
    public static void Hide() => _service.HideLoading();
}

使用示例:

LoadingManager.Show("正在加载数据...");
await SomeAsyncTask();
LoadingManager.Hide();

方案二:纯代码动态创建Xamarin.Forms加载覆盖层

完全基于Xamarin.Forms控件通过代码动态生成,无需依赖原生实现,适配所有支持平台(包括UWP)。

封装调用类

public static class DynamicLoadingOverlay
{
    private static ContentView _overlay;

    public static void Show(Page currentPage, string message = "加载中...")
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            var indicator = new ActivityIndicator
            {
                IsRunning = true,
                Color = Color.Accent,
                VerticalOptions = LayoutOptions.Center,
                HorizontalOptions = LayoutOptions.Center
            };

            var messageLabel = new Label
            {
                Text = message,
                TextColor = Color.White,
                Margin = new Thickness(0, 10, 0, 0),
                HorizontalOptions = LayoutOptions.Center
            };

            var stackLayout = new StackLayout
            {
                Children = { indicator, messageLabel },
                BackgroundColor = Color.Black.WithAlpha(0.7),
                Padding = new Thickness(20),
                CornerRadius = 8
            };

            _overlay = new ContentView
            {
                Content = stackLayout,
                BackgroundColor = Color.Transparent,
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                GestureRecognizers = { new TapGestureRecognizer() } // 阻止点击穿透
            };

            currentPage.Content = new Grid
            {
                Children =
                {
                    currentPage.Content,
                    _overlay
                }
            };
        });
    }

    public static void Hide(Page currentPage)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            if (_overlay != null && currentPage.Content is Grid grid)
            {
                grid.Children.Remove(_overlay);
                currentPage.Content = grid.Children[0];
                _overlay = null;
            }
        });
    }
}

调用示例

// 显示加载
DynamicLoadingOverlay.Show(this, "处理中...");
// 执行异步操作
await YourAsyncOperation();
// 隐藏加载
DynamicLoadingOverlay.Hide(this);

方案三:基于Prism Popup(项目已集成Prism框架时使用)

若项目已经使用Prism框架,可利用其Popup功能纯代码创建加载指示器,天然支持UWP平台。

1. 创建纯代码PopupPage

public class LoadingPopupPage : PopupPage
{
    public LoadingPopupPage(string message)
    {
        BackgroundColor = Color.Black.WithAlpha(0.5);

        var indicator = new ActivityIndicator
        {
            IsRunning = true,
            Color = Color.White,
            WidthRequest = 40,
            HeightRequest = 40
        };

        var messageLabel = new Label
        {
            Text = message,
            TextColor = Color.White,
            Margin = new Thickness(0, 10, 0, 0)
        };

        Content = new StackLayout
        {
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center,
            Children = { indicator, messageLabel },
            BackgroundColor = Color.DarkGray,
            Padding = new Thickness(20),
            CornerRadius = 10
        };
    }
}

2. 调用方式

通过Prism的IPopupNavigation服务调用:

// 构造函数注入IPopupNavigation
private readonly IPopupNavigation _popupNavigation;
public YourViewModel(IPopupNavigation popupNavigation)
{
    _popupNavigation = popupNavigation;
}

// 显示加载
await _popupNavigation.PushAsync(new LoadingPopupPage("加载中..."));
// 异步操作
await SomeTask();
// 隐藏加载
await _popupNavigation.PopAsync();

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:43:19