【问题标题】:Xamarin.Forms ActivityIndicator in Toolbar/Navigation Bar工具栏/导航栏中的 Xamarin.Forms ActivityIndi​​cator
【发布时间】:2018-03-07 08:43:57
【问题描述】:

我有一个遵循 MVVM 模式的多页(Android 和 iOS)Xamarin.Forms 应用程序。有时,业务逻辑可能会调用重要的活动,例如触发与某些 Web 服务的数据同步。我不想向用户显示后台发生了一些事情。工具栏中的 ActivityIndi​​cator 将是我理想的解决方案。该活动与前台的页面无关,所以我不想将指示器放在页面上,我希望它在外面的某个地方,工具栏似乎是正确的位置。

我的第一次尝试是通过 XAML:

<ContentPage.ToolbarItems>
    <ToolbarItem>
        <ActivityIndicator IsRunning="{Binding IsRunning}" />
    </ToolbarItem>
</ContentPage.ToolbarItems>

虽然这种(和类似的方法)可以编译,但它会抛出异常,似乎 ActivityIndi​​cator 不可能是 ToolbarItems 或任何 Toolbar Item 的子项。

翻转手册页我偶然发现了页面类的 IsBusy 属性。

https://developer.xamarin.com/api/property/Xamarin.Forms.Page.IsBusy/

为了尝试,我使用了以下代码:

public App ()
{
    InitializeComponent();
    MainPage = new App1.MainPage();
    MainPage.IsBusy = true;
}

结果是——什么都没有。没有错误,但工具栏中没有显示任何内容。我在论坛中发现了一些迹象,表明此功能可能已在最新的 Android 版本中被丢弃,但没有确定的内容,文档也没有这么说。

我怎样才能实现我想要的?

【问题讨论】:

    标签: xamarin.forms toolbar activity-indicator


    【解决方案1】:

    这是可以在您的 PCL 和 Android 项目中使用的代码,遗憾的是我目前还没有编写 iOS 自定义渲染器。无论如何,您需要在您的 PCL 中自定义 NavigationPage,并在您的 Android 项目中自定义 NavigationPageRenderer

    CustomNavigationPage.cs(在您的 PCL 项目中):

    public class CustomNavigationPage : NavigationPage
    {
        public event EventHandler<EventArgs> OnShowActivityIndicator;
        public event EventHandler<EventArgs> OnHideActivityIndicator;
    }
    

    CustomNavigationPageRenderer.cs(在您的 Android 项目中):

    [assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(CustomNavigationPageRenderer))]
    namespace MyProject.Droid.CustomRenderers
    {
        CustomNavigationPage page;
        Android.Support.V7.Widget.Toolbar _toolbar;
        Android.Widget.ProgressBar _progressBar;
        bool _isProgressBarCurrentlyOnToolBar = false;
    
        public class CustomNavigationPageRenderer : NavigationPageRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<CustomNavigationPage> e)
            {
                base.OnElementChanged(e);
    
                if (e.NewElement != null)
                {
                    page = (CustomNavigationPage)e.NewElement;
                    page.OnShowActivityIndicator += HandleShowActivityIndicator;
                    page.OnHideActivityIndicator += HandleHideActivityIndicator;
                }
            }
    
            private void HandleShowActivityIndicator(object sender, EventArgs e)
            {
                var progressBar = GetProgressBar();
                if (progressBar == null)
                    return;
    
                var toolbar = GetToolbar();
                if (toolbar == null)
                    return;
    
                Device.BeginInvokeOnMainThread(() => 
                {
                    if (_isProgressBarCurrentlyOnToolBar == false)
                    {
                        toolbar.AddView(progressBar);
                        _isProgressBarCurrentlyOnToolBar = true;
                    }
                });
            }
    
            private void HandleHideActivityIndicator(object sender, EventArgs e)
            {
                var progressBar = GetProgressBar();
                if (progressBar == null)
                    return;
    
                var toolbar = GetToolbar();
                if (toolbar == null)
                    return;
    
                Device.BeginInvokeOnMainThread(() => 
                {
                    if (_isProgressBarCurrentlyOnToolBar)
                    {
                        toolbar.RemoveView(progressBar);
                        _isProgressBarCurrentlyOnToolBar = false;
                    }
                });
            }
    
            private Android.Support.V7.Widget.Toolbar GetToolbar()
            {
                if (_toolbar == null)
                {
                    for (var i = 0; i < this.ChildCount; i++)
                    {
                        var child = GetChildAt(i);
    
                        if (child.GetType() == typeof(Android.Support.V7.Widget.Toolbar))
                        {
                            _toolbar = (Android.Support.V7.Widget.Toolbar)child;
                        }
                    }
                }
    
                return _toolbar;
            }
    
            private Android.Widget.ProgressBar GetProgressBar()
            {
                if (_progressBar == null)
                {
                    _progressBar = new Android.Widget.ProgressBar(Xamarin.Forms.Forms.Context)
                    {
                        Indeterminate = true,
                        LayoutParameters = new LayoutParams(Utils.PxToDip(20), Utils.PxToDip(20))
                    };
                    _progressBar.SetPadding(10, 0, 0, 0);
                }
    
                return _progressBar;
            }
    
        }
    }
    

    使用它很简单,在你的代码后面简单地调用事件处理程序。即:

    public class MyPage : CustomNavigationPage
    {
        public MyPage()
        {
            // show it:
            OnShowActivityIndicator?.Invoke(this, null);
    
            // hide it:
            OnHideActivityIndicator?.Invoke(this, null);
        }
    }
    

    【讨论】:

    • 哇!非常感谢sn-p。我会尽快检查的!
    • 没问题,我看看能不能得到一些iOS的工作代码
    • 那真是太好了,很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2015-02-24
    • 2021-11-26
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    相关资源
    最近更新 更多