简体   繁体   中英

Display text while Page is loading in Xamarin Forms

I have a page that is quite heavy and its loading for about 1-2 sec after click. During this time I see loading page header and old page content, it looks so irresponsive. All I want to achive is to display temporary Label with content like "Loading..." or activityindicator as long as new page is loading but I have no idea how to do this. What is the better way to achive this? Thanks in advance

Based on your comments, you just want to display Busy indicator while you are loading the Data from your Api. You didn't posted your UI but I hope you understand how to use the below:

<Grid>
     <YOUR-UI>
         .....
         .........
     </YOUR-UI>

     <ActivityIndicator VerticalOptions="Center" IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}"/>
</Grid>

In your ViewModel, Add IsBusy Property as below:

private bool _isBusy;
public bool IsBusy
{
    get{return _isBusy;}
    set { _isBusy=value; RaisePropertyChanged(); }
}

Then when you are Calling the API to load your Data do something like:

public async void LoadDataFromApi()
{
    IsBusy=true;  //Show the Indicator
    var response= await YourService.Method();  //this is where you calling your api
    //do other stuffs if you need to do;
    IsBusy=false;   //Hide the Indicator
}

Let me know if you need anymore help.

Based on your comments on other answer - instead of ActivityIndicator - you could use a simple frame that covers all the layout and make it visible only when data are loading ie Binding IsVisible to IsBusy property. Then set IsBusy to true before doing the heavy load job and set back to false afterwards as shown in previous answer.

For instance, assuming your UI is based on a Grid layout (in this example 3 rows/2 columns):

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <!-- Some XAML for the grid content -->

    <!-- Here, Frame covers all the possible space defined using RowSpan/ColumnSpan -->
    <Frame Grid.RowSpan="3" Grid.ColumnSpan="2" IsVisible="{Binding IsBusy}" BackgroundColor="LightGray">
       <Label VerticalOptions="Center" HorizontalOptions="Center" Text="Loading Samples..." />
    </Frame>
</Grid>

查看结果

-------------------------------------------------

EDIT based on OP comments:

Bases on the code you provided (better paste it in SO next time ;)), you could try this:

Add a grid layout and a frame to the xaml page:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.Namespace"    
             xmlns:tabView="clr-namespace:Syncfusion.XForms.TabView;assembly=Syncfusion.SfTabView.XForms"
             xmlns:sfPopup="clr-namespace:Syncfusion.XForms.PopupLayout;assembly=Syncfusion.SfPopupLayout.XForms" 
             BackgroundColor="#d4d4d4">

    <ContentPage.ToolbarItems>
        <ToolbarItem Icon="search_white_90.png"/>
    </ContentPage.ToolbarItems>
    <ContentPage.Content>
        <Grid>
            <tabView:SfTabView x:Name="ProductsTabView" VisibleHeaderCount="3" TabHeaderBackgroundColor="#A74B40" Items="{Binding}">
                <tabView:SfTabView.SelectionIndicatorSettings>
                    <tabView:SelectionIndicatorSettings
                        Color="#fff" StrokeThickness="3"/>
                </tabView:SfTabView.SelectionIndicatorSettings>
            </tabView:SfTabView>
            <Frame x:Name="theFrame" BackgroundColor="White">
               <Label VerticalOptions="Center" HorizontalOptions="Center" Text="Loading Samples..." />
            </Frame>
        </Grid>
    </ContentPage.Content>
</ContentPage>

ProductsTabView and theFrame will cover the same space on screen and frame will be available in code behind. Then you can show/hide theFrame before/afrer the hard work using IsVisible property:

public partial class ProviderPage : ContentPage
    {
        public ProviderPage()
        {
            InitializeComponent();            
            theFrame.IsVisible = true; // Show the Frame on top of tabView
            ProductsTabView.Items = GetTabItemCollection();    
            theFrame.IsVisible = false; // Hide the Frame
        }
        ...

As a side note, you don't use ViewModel at all. I strongly recommand you to check about what a ViewModel is and how to use them with MVVM pattern. It will make your life easier in the long run using Binding !

HIH & Happy coding!

Try https://github.com/aritchie/userdialogs , It's make you easily to implement loading

for example:

 using (this.Dialogs.Loading("Loading text"))
    {
         //Do something i.e: await Task.Delay(3000);
    }   

OR

this.Dialogs.ShowLoading("Loading text");
//Do something i.e: await Task.Delay(3000);
this.Dialogs.HideLoading();    

OR https://github.com/aritchie/userdialogs/blob/master/src/Samples/Samples/ViewModels/ProgressViewModel.cs

I have a project for advanced page transitions in Xamarin.Forms that may help you. Try this:

  1. Install this nuget: http://www.nuget.org/packages/Xamarin.Forms.Segues (it is currently only prerelease, so you'll need to check the box to see it)
  2. Add this sample to your project: https://github.com/chkn/Xamarin.Forms.Segues/blob/master/Sample/Shared/Custom%20Segues/SpinnerSegue.cs
  3. In the DoWork method of SpinnerSegue add the code to load the data.
  4. In your code that navigates to the other page, replace Navigiation.PushAsync(new MyNewPage()) with new SpinnerSegue().ExecuteAsync(this, new MyNewPage())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM