Algumas vezes é necessário indicar para o usuário que o aplicativo está realizando alguma atividade, ou mesmo para que ele não pense que o app travou.
Um exemplo bastante comum é quando necessita ser realizada uma requisição ao servidor e a internet do usuário está um pouco lenta, enquanto a requisição não termina, é preciso informar ao usuário que algo está ocorrendo ali, por isso então, é usado o Loading ou também conhecido como indicador de atividade. Podendo ser de diferentes formas, neste post irei demonstrar como criar o indicador de atividade padrão das três principais plataformas, sendo elas:
Android
iOS
UWP
Para este exemplo, crie um botão para chamar o método “Show” e abaixo do botão adicione um ActivityIndicator como demonstrado a seguir.
XAML
<?xml version="1.0" encoding="utf-8" ?> | |
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" | |
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |
xmlns:local="clr-namespace:DemoLoading" | |
x:Class="DemoLoading.DemoLoadingPage" > | |
<StackLayout > | |
<Button x:Name="botao" Clicked="Show" Text="Login" TextColor="White" BackgroundColor="#3b5998" Margin="10,30,10,30"/> | |
<ActivityIndicator x:Name="actInd" | |
IsRunning="{Binding IsLoading}" | |
IsVisible="{Binding IsLoading}" Color="Red"/> | |
</StackLayout> | |
</ContentPage> |
Em seguida, no Code-Behind crie o método RaisePropertyChanged e a variável do tipo bool chamada de IsLoading, sete ela como false no método construtor da classe e por último crie o método Show como demonstrado a seguir.
Code-Behind
using System; | |
using System.ComponentModel; | |
using System.Threading.Tasks; | |
using Xamarin.Forms; | |
namespace DemoLoading | |
{ | |
public partial class MainPage : ContentPage, INotifyPropertyChanged | |
{ | |
public MainPage() | |
{ | |
InitializeComponent(); | |
IsLoading = false; | |
BindingContext = this; | |
} | |
public async void Show(object sender, EventArgs e) | |
{ | |
try | |
{ | |
aparece(); | |
//Chame sua função aqui | |
await Task.Delay(4000); | |
some(); | |
} | |
catch (Exception ex) | |
{ | |
some(); | |
if (ex != null) | |
{ | |
//Trate seu erro aqui | |
} | |
} | |
} | |
public async void aparece() | |
{ | |
IsLoading = true; | |
} | |
public async void some() | |
{ | |
IsLoading = false; | |
} | |
private bool isLoading; | |
public bool IsLoading | |
{ | |
get | |
{ | |
return this.isLoading; | |
} | |
set | |
{ | |
this.isLoading = value; | |
RaisePropertyChanged("IsLoading"); | |
} | |
} | |
public event PropertyChangedEventHandler PropertyChanged; | |
public void RaisePropertyChanged(string name) | |
{ | |
if (PropertyChanged != null) | |
{ | |
PropertyChanged(this, new PropertyChangedEventArgs(name)); | |
} | |
} | |
} | |
} |
Neste caso para fins de exemplo, no método Show apenas criei um Delay para que o ActivityIndicator apareça e depois de um tempo desapareça.
Resultado
Android
iOS
UWP
Esse e todos os exemplos deste blog encontram-se disponíveis no GitHub.
Sou novo no trabalho com Xamarin e seus posts estão me ajudando muito. Parabéns! Gostaria de saber se ao habilitar o indicator teria como travar a tela para o usuário não mexer até o processamento terminar
CurtirCurtir
Olá Frederico, obrigado ! Fico feliz em saber que os post’s estão te ajudando.
Tem sim, sabe a variável IsLoading ? Crie uma igual, e faça um binding na propriedade isEnabled.
Montei um exemplo e chamei a variável de isDisabled.
Acabei de subir no github, da uma olhada lá.
Espero ter ajudado.
CurtirCurtir
Ola Frederico, tudo bem?
Tentei realizar o teste com o seu exemplo, mas não consegui exibir a animação do loading. Aparece tudo normalmente…até debuguei para ver se estava chamando os métodos corretamente. O que pode ser?
CurtirCurtir
Olá Gustavo,
Verifique se você está setando o BindingContext no método construtor.
Verifique também se você está utilizando o INotifyPropertyChanged.
CurtirCurtir
Ola Frederico, muito obrigado pelo retorno. Realmente eu tinha esquecido de colocar o INotifyPropertyChanged. Valeu mesmo!!! Gostei muito de seus posts!!!
CurtirCurtir
Parabéns Juliano excelente artigo.
Uma dúvida este exemplo pode ser utilizado na espera da resposta de uma webApi ?
Eu fiz da forma que você exemplificou e funciona perfeitamente, mais ele tem este Delay de 4000, que acredito que talvez a resposta da Api, possa demorar mais do que o tempo determinado.
Seria viável fazer desta forma ?
Obrigado, =]
CurtirCurtir
Olá Gleidson,
Obrigado 🙂
Sim, é viável.
O Delay de 4000 eu utilizei apenas para exemplificar, substitua essa linha pela chamada da sua API, observe que é ativado o loading antes do Delay e finalizado depois, se você substituir o Delay pela chamada da sua API, o loading será ativado antes e desativado após o termino da sua chamada. (Lembre-se de utilizar async e await)
Qualquer dúvida estou a disposição.
CurtirCurtir
Boa tarde Juliano, tudo bem?
Gostei muito do artigo, as fiquei com uma dúvida: tem como bloquear toda a tela durante o loader? No caso da sua resposta ao Frederico, o isEnabled bloquearia apenas um botão, certo? Como fazer nos casos onde existem vários botões na tela? Como por exemplo na tela de login, onde posso realizar o login, ou navegar paras as telas de criação e recuperação de senha? Teria que colocar um isEnabled em cada um?
Muito obrigado.
Abraços.
CurtirCurtir
Olá André, tudo bem e você ?
Outra alternativa fácil é, Coloque todos os elementos da tela dentro de um StackLayout, exceto o ActivityIndicator. De um nome para esse StackLayout e apenas utilize o NomeStackLayout.IsVisible, false enquanto aparece o Loading e True quando sumir.
Espero ter ajudado.
Abraços
CurtirCurtir
Boa noite Juliano,
Cara, sou novo no desenvolvimento com xamarin e seus posts tem me ajudado muito.
Seus posts são simples e objetivo e vão direto ao ponto… show de bola!!
CurtirCurtir
Olá William,
Fico feliz em saber que os meus posts estão te ajudando. 😀
CurtirCurtir