Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O pull-to-refresh permite que um usuário puxe para baixo uma lista de dados usando o toque para recuperar mais dados. Pull-to-refresh é amplamente utilizado em dispositivos com tela sensível ao toque. Você pode usar as APIs mostradas aqui para implementar o pull-to-refresh em seu aplicativo.
Será este o controlo correto?
Utilize a funcionalidade de puxar-para-atualizar quando tiver uma lista ou grelha de dados que o utilizador queira atualizar regularmente e é provável que a sua aplicação seja executada em dispositivos otimizados para toque.
Você também pode usar o RefreshVisualizer para criar uma experiência de atualização consistente que é invocada de outras maneiras, como por um botão de atualização.
Controles de atualização
Pull-to-refresh é ativado por 2 controles.
- RefreshContainer - um ContentControl que fornece um envoltório para a experiência de puxar para atualizar. Ele lida com as interações por toque e gerencia o estado de seu visualizador de atualização interno.
- RefreshVisualizer - encapsula a visualização de atualização explicada na próxima seção.
O controle principal é o RefreshContainer, que você coloca como um wrapper em torno do conteúdo que o usuário extrai para disparar uma atualização. RefreshContainer funciona apenas com toque, por isso recomendamos que você também tenha um botão de atualização disponível para usuários que não têm uma interface de toque. Você pode posicionar o botão de atualização em um local adequado no aplicativo, em uma barra de comandos ou em um local próximo à superfície que está sendo atualizada.
Atualizar visualização
A visualização de atualização padrão é um girador de progresso circular que é usado para comunicar quando uma atualização acontecerá e o progresso da atualização depois que ela for iniciada. O visualizador de atualização tem 5 estados.
A distância que o usuário precisa puxar para baixo em uma lista para iniciar uma atualização é chamada de limite. O estado do visualizador é determinado pelo estado de pull em relação a esse limite. Os valores possíveis estão contidos na enumeração RefreshVisualizerState .
Idle
O estado padrão do visualizador é Ocioso. O usuário não está interagindo com o RefreshContainer via toque e não há uma atualização em andamento.
Visualmente, não há evidências do visualizador de atualização.
Interagindo
Quando o usuário puxa a lista na direção especificada pela propriedade PullDirection e antes que o limite seja atingido, o visualizador está no estado Interagindo .
Se o usuário liberar o controle enquanto estiver nesse estado, o controle retornará para Ocioso.
Visualmente, o ícone é exibido como desativado (60% opacidade). Além disso, o ícone realiza uma rotação completa com a ação de rolagem.
Se o usuário puxar a lista além do limite, o visualizador fará a transição de Interagindo para Pendente.
Visualmente, o ícone altera para 100% de opacidade e pulsa em tamanho até 150%, retornando depois para 100% de tamanho durante a transição.
Pendente
Quando o utilizador tiver puxado a lista além do limite, o visualizador estará no estado Pendente.
- Se o utilizador mover a lista de volta acima do limiar sem a libertar, a lista retornará ao estado Interagindo.
- Se o usuário liberar a lista, uma solicitação de atualização será iniciada e ela passará para o estado Atualizando .
Visualmente, o ícone tem 100% de tamanho e opacidade. Nesse estado, o ícone continua a se mover para baixo com a ação de rolagem, mas não gira mais.
A atualizar
Quando o usuário libera o visualizador além do limite, ele está no estado Atualizando .
Quando esse estado é inserido, o evento RefreshRequested é gerado. Este é o sinal para iniciar a atualização de conteúdo do aplicativo. Os argumentos do evento (RefreshRequestedEventArgs) contêm um objeto Deferral, para o qual deve usar um identificador no manipulador de eventos. Em seguida, deverá marcar o adiamento como concluído quando o seu código para executar a atualização estiver finalizado.
Quando a atualização estiver concluída, o visualizador retornará ao estado Inativo.
Visualmente, o ícone volta à posição inicial e gira sobre ele mesmo durante a atualização de ecrã. Essa rotação é usada para mostrar o progresso da atualização e é substituída pela animação do conteúdo recebido.
Espreitar
Quando o utilizador puxa na direção de atualização a partir de um ponto inicial onde não é permitido atualizar, o visualizador entra no estado Peeking. Isso normalmente acontece quando o ScrollViewer não está na posição 0 quando o usuário começa a puxar.
- Se o usuário liberar o controle enquanto estiver nesse estado, o controle retornará para Ocioso.
Direção de tração
Por padrão, o usuário puxa uma lista de cima para baixo para iniciar uma atualização. Se você tiver uma lista ou grade com uma orientação diferente, altere a direção de tração do contêiner de atualização para corresponder.
A propriedade PullDirection usa um destes valores RefreshPullDirection : BottomToTop, TopToBottom, RightToLeft ou LeftToRight.
Quando alteras a direção de puxar, a posição inicial do indicador circular de progresso do visualizador gira automaticamente, de modo que a seta comece na posição adequada para a direção de puxar. Se necessário, você pode alterar a propriedade RefreshVisualizer.Orientation para substituir o comportamento automático. Na maioria dos casos, recomendamos deixar o valor padrão de Auto.
Implementar a função de "puxar para atualizar"
- APIs importantes: RefreshContainer, RefreshVisualizer
O aplicativo WinUI 3 Gallery inclui exemplos interativos da maioria dos controles, recursos e funcionalidades do WinUI 3. Obtenha o aplicativo no da Microsoft Store ou obtenha o código-fonte em do GitHub
Para adicionar a funcionalidade pull-to-refresh a uma lista são necessárias apenas algumas etapas.
- Envolva a lista num controlo de RefreshContainer
. - Manipule o evento RefreshRequested para atualizar seu conteúdo.
- Opcionalmente, inicie uma atualização chamando RequestRefresh (por exemplo, a partir de um clique no botão).
Observação
Você pode instanciar um RefreshVisualizer sozinho. No entanto, recomendamos que envolva o seu conteúdo num RefreshContainer e utilize o RefreshVisualizer fornecido pela propriedade RefreshContainer.Visualizer, mesmo para cenários sem toque. Neste artigo, assumimos que o visualizador é sempre obtido a partir do container de atualização.
Além disso, para conveniência, utilize os membros RequestRefresh e RefreshRequested do contêiner de atualização.
refreshContainer.RequestRefresh() é equivalente a refreshContainer.Visualizer.RequestRefresh(), e qualquer um deles gerará o evento RefreshContainer.RefreshRequested e os eventos RefreshVisualizer.RefreshRequested.
Solicite uma atualização
O contêiner de atualização lida com interações por toque para permitir que um usuário atualize o conteúdo por toque. Recomendamos que você forneça outros recursos para interfaces sem toque, como um botão de atualização ou controle de voz.
Para iniciar uma atualização, chame o método RequestRefresh .
// See the Examples section for the full code.
private void RefreshButtonClick(object sender, RoutedEventArgs e)
{
RefreshContainer.RequestRefresh();
}
Quando você chama RequestRefresh, o estado do visualizador vai diretamente de Idle para Refreshing.
Lidar com uma solicitação de atualização
Para obter conteúdo novo quando necessário, manipule o evento RefreshRequested. No manipulador de eventos, você precisará de código específico para seu aplicativo para obter o conteúdo novo.
O evento args (RefreshRequestedEventArgs) contém um objeto Deferral . Obtenha um identificador para o adiamento no manipulador de eventos. Em seguida, marque o adiamento como concluído quando o código que executa a atualização for concluído.
// See the Examples section for the full code.
private async void RefreshContainer_RefreshRequested(RefreshContainer sender, RefreshRequestedEventArgs args)
{
// Respond to a request by performing a refresh and using the deferral object.
using (var RefreshCompletionDeferral = args.GetDeferral())
{
// Do some async operation to refresh the content
await FetchAndInsertItemsAsync(3);
// The 'using' statement ensures the deferral is marked as complete.
// Otherwise, you'd call
// RefreshCompletionDeferral.Complete();
// RefreshCompletionDeferral.Dispose();
}
}
Responder a alterações de estado
Você pode responder a alterações no estado do visualizador, se necessário. Por exemplo, para evitar várias solicitações de atualização, você pode desativar um botão de atualização enquanto o visualizador está atualizando.
// See the Examples section for the full code.
private void Visualizer_RefreshStateChanged(RefreshVisualizer sender, RefreshStateChangedEventArgs args)
{
// Respond to visualizer state changes.
// Disable the refresh button if the visualizer is refreshing.
if (args.NewState == RefreshVisualizerState.Refreshing)
{
RefreshButton.IsEnabled = false;
}
else
{
RefreshButton.IsEnabled = true;
}
}
Usando um ScrollViewer em um RefreshContainer
Observação
O conteúdo de um RefreshContainer deve ser um controle rolável, como ScrollViewer, GridView, ListView, etc. Definir o Conteúdo para um controle como Grid resultará em um comportamento indefinido.
Este exemplo mostra como usar pull-to-refresh com um visualizador de rolagem.
<RefreshContainer>
<ScrollViewer VerticalScrollMode="Enabled"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<!-- Scrollviewer content -->
</ScrollViewer>
</RefreshContainer>
Adicionando a funcionalidade de arrastar-para-atualizar a um ListView
Este exemplo mostra como usar o gesto de "arrastar para atualizar" com uma visualização de lista.
<StackPanel Margin="0,40" Width="280">
<CommandBar OverflowButtonVisibility="Collapsed">
<AppBarButton x:Name="RefreshButton" Click="RefreshButtonClick"
Icon="Refresh" Label="Refresh"/>
<CommandBar.Content>
<TextBlock Text="List of items"
Style="{StaticResource TitleTextBlockStyle}"
Margin="12,8"/>
</CommandBar.Content>
</CommandBar>
<RefreshContainer x:Name="RefreshContainer">
<ListView x:Name="ListView1" Height="400">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:ListItemData">
<Grid Height="80">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="{x:Bind Path=Header}"
Style="{StaticResource SubtitleTextBlockStyle}"
Grid.Row="0"/>
<TextBlock Text="{x:Bind Path=Date}"
Style="{StaticResource CaptionTextBlockStyle}"
Grid.Row="1"/>
<TextBlock Text="{x:Bind Path=Body}"
Style="{StaticResource BodyTextBlockStyle}"
Grid.Row="2"
Margin="0,4,0,0" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RefreshContainer>
</StackPanel>
public sealed partial class MainPage : Page
{
public ObservableCollection<ListItemData> Items { get; set; }
= new ObservableCollection<ListItemData>();
public MainPage()
{
this.InitializeComponent();
Loaded += MainPage_Loaded;
ListView1.ItemsSource = Items;
}
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Loaded -= MainPage_Loaded;
RefreshContainer.RefreshRequested += RefreshContainer_RefreshRequested;
RefreshContainer.Visualizer.RefreshStateChanged += Visualizer_RefreshStateChanged;
// Add some initial content to the list.
await FetchAndInsertItemsAsync(2);
}
private void RefreshButtonClick(object sender, RoutedEventArgs e)
{
RefreshContainer.RequestRefresh();
}
private async void RefreshContainer_RefreshRequested(RefreshContainer sender, RefreshRequestedEventArgs args)
{
// Respond to a request by performing a refresh and using the deferral object.
using (var RefreshCompletionDeferral = args.GetDeferral())
{
// Do some async operation to refresh the content
await FetchAndInsertItemsAsync(3);
// The 'using' statement ensures the deferral is marked as complete.
// Otherwise, you'd call
// RefreshCompletionDeferral.Complete();
// RefreshCompletionDeferral.Dispose();
}
}
private void Visualizer_RefreshStateChanged(RefreshVisualizer sender, RefreshStateChangedEventArgs args)
{
// Respond to visualizer state changes.
// Disable the refresh button if the visualizer is refreshing.
if (args.NewState == RefreshVisualizerState.Refreshing)
{
RefreshButton.IsEnabled = false;
}
else
{
RefreshButton.IsEnabled = true;
}
}
// App specific code to get fresh data.
private async Task FetchAndInsertItemsAsync(int updateCount)
{
for (int i = 0; i < updateCount; ++i)
{
// Simulate delay while we go fetch new items.
await Task.Delay(1000);
Items.Insert(0, GetNextItem());
}
}
private ListItemData GetNextItem()
{
return new ListItemData()
{
Header = "Header " + DateTime.Now.Second.ToString(),
Date = DateTime.Now.ToLongDateString(),
Body = DateTime.Now.ToLongTimeString()
};
}
}
public class ListItemData
{
public string Header { get; set; }
public string Date { get; set; }
public string Body { get; set; }
}
UWP e WinUI 2
Importante
As informações e exemplos neste artigo são otimizados para aplicativos que usam o SDK de Aplicativos Windows e WinUI 3, mas geralmente são aplicáveis a aplicativos UWP que usam WinUI 2. Consulte a referência da API UWP para obter informações e exemplos específicos da plataforma.
Esta seção contém informações que você precisa para usar o controle em um aplicativo UWP ou WinUI 2.
Os controles de atualização para aplicativos UWP estão incluídos como parte da WinUI 2. Para obter mais informações, incluindo instruções de instalação, consulte WinUI 2. As APIs para esse controle existem nos namespaces Windows.UI.Xaml.Controls (UWP) e Microsoft.UI.Xaml.Controls (WinUI).
- APIs UWP:RefreshContainer, RefreshVisualizer
- WinUI 2 API:RefreshContainer, RefreshVisualizer
- Abra o aplicativo WinUI 2 Gallery e veja PullToRefresh em ação. O aplicativo WinUI 2 Gallery inclui exemplos interativos da maioria dos controles, recursos e funcionalidades do WinUI 2. Obtenha o aplicativo da Microsoft Store ou obtenha o código-fonte no GitHub.
Recomendamos usar a WinUI 2 mais recente para obter os estilos, modelos e recursos mais atuais para todos os controles.
Para usar o código neste artigo com WinUI 2, use um alias em XAML (usamos muxc) para representar as APIs da Biblioteca da Interface do Usuário do Windows incluídas em seu projeto. Consulte Introdução ao WinUI 2 para obter mais informações.
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:RefreshContainer />
Artigos relacionados
Windows developer