0
votes

I'm developing a Xamarin Forms application. I want to show an ActivityIndicator while getting data & binding it to a ListView control from web API. In my code, ActivityIndicator doesn't show at all. I'm using Visual Studio 2017 with Xamarin 4.10.

Following is my code.

Code Behind

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestPage : ContentPage
{
    private SfListView listView;
    private ActivityIndicator activityIndicator;

    public TestPage()
    {
        InitializeComponent();

        StackLayout mainStackLayout = new StackLayout();

        activityIndicator = new ActivityIndicator()
        {
            IsRunning = true,
            IsEnabled = true,
            IsVisible = true
        };
        listView = new SfListView()
        {
            SelectionMode = SelectionMode.None,
            BackgroundColor = Color.White
        };

        mainStackLayout.Children.Add(activityIndicator);
        mainStackLayout.Children.Add(listView);

        this.Content = mainStackLayout;
        this.Title = "Dashboard";
    }

    protected override void OnAppearing()
    {
        SummaryRepository viewModel = new SummaryRepository();

        listView.ItemsSource = viewModel.Summary;
        listView.ItemTemplate = new DataTemplate(() =>
        {
            var grid = new Grid();

            var bookName = new Label
            {
                BackgroundColor = Color.White,
                FontSize = 16,
                TextColor = Color.FromHex("#1A237E")
            };
            var bookDescription = new Label
            {
                BackgroundColor = Color.White,
                FontSize = 16,
                HorizontalTextAlignment = TextAlignment.End,
                TextColor = Color.FromHex("#EC407A")
            };

            bookName.SetBinding(Label.TextProperty, new Binding("Name"));
            bookDescription.SetBinding(Label.TextProperty, new Binding("Amount"));

            grid.Children.Add(bookName);
            grid.Children.Add(bookDescription, 1, 0);

            return grid;
        });

        activityIndicator.IsRunning = false;

        base.OnAppearing();
    }
}

XAML File

<?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="eWallet.Pages.TestPage">
<ContentPage.Content>
    <StackLayout>

    </StackLayout>
</ContentPage.Content>

Any help is highly appreciated.

3

3 Answers

1
votes

Use this code :

<ContentPage.Content>
        <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <StackLayout BackgroundColor="#F5F5F5" VerticalOptions="FillAndExpand" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
               //Your Listview
            </StackLayout>
            <StackLayout Padding="12" x:Name="DisplayLoading" IsVisible="False"
                 AbsoluteLayout.LayoutFlags="PositionProportional"
                 AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
                <ActivityIndicator Color="#d7813e" IsRunning="True"/>
                <Label Text="Loading..." TextColor="#d7813e" FontSize="Small"/>
            </StackLayout>
        </AbsoluteLayout>       
    </ContentPage.Content>

And in cs file use :

protected override void OnAppearing()
    {
        activityIndicator.IsRunning = true;
        SummaryRepository viewModel = new SummaryRepository();

        listView.ItemsSource = viewModel.Summary;
        listView.ItemTemplate = new DataTemplate(() =>
        {
            var grid = new Grid();

            var bookName = new Label
            {
                BackgroundColor = Color.White,
                FontSize = 16,
                TextColor = Color.FromHex("#1A237E")
            };
            var bookDescription = new Label
            {
                BackgroundColor = Color.White,
                FontSize = 16,
                HorizontalTextAlignment = TextAlignment.End,
                TextColor = Color.FromHex("#EC407A")
            };

            bookName.SetBinding(Label.TextProperty, new Binding("Name"));
            bookDescription.SetBinding(Label.TextProperty, new Binding("Amount"));

            grid.Children.Add(bookName);
            grid.Children.Add(bookDescription, 1, 0);

            return grid;
        });

        activityIndicator.IsRunning = false;

        base.OnAppearing();
    }
0
votes

My guess would be that OnAppearing method is fetching the data and binding into the listview source synchronously, which means that when the view is created, the data is already binded and the activityIndicator.IsRunning = false; disappears the indicator. So you dont actually see it running. Because when the view is shown the binding is already completed and indicator is false.

One suggestion is that..

Listview already has IsRefreshing property, set this to true and you will see the indicator running, false to disappear.

You can also use IsPullToRefreshEnabled to true so the user can actually pull down the listview to show the indicator running and invoke refresh command so you can do refresh method here.

Hope this help

0
votes

Probably, what is happening is exactly what Luminous said. You are calling activityIndicator.IsRunning = false; on OnAppearing() method, so, if the fetch goes to fast, you're not going to see the activity indicator. Try to use a Thread.Sleep(2000) to check if that's the case.