Przeciągnij, aby odświeżyć
Funkcja pull-to-refresh umożliwia użytkownikowi przesunięcie listy danych w dół przy użyciu dotyku w celu załadowania większej ilości danych. Funkcja ściągania do odświeżania jest powszechnie używana na urządzeniach z ekranem dotykowym. Interfejsy API pokazane tutaj umożliwiają zaimplementowanie funkcji pull-to-refresh w aplikacji.
gif "pull-to-refresh"
Czy jest to właściwa kontrola?
Użyj funkcji pull-to-refresh, gdy masz listę lub siatkę danych, które użytkownik może chcieć odświeżyć regularnie, a aplikacja prawdopodobnie będzie działać na urządzeniach z obsługą dotykową.
Możesz również użyć RefreshVisualizer, aby utworzyć spójne wrażenia odświeżania, które są wywoływane na inne sposoby, takie jak za pomocą przycisku odświeżania.
Odśwież kontrolki
Funkcja ściągania do odświeżania jest włączona przez 2 kontrolki.
- RefreshContainer — kontrolka ContentControl zapewniająca otokę dla doświadczenia przeciągania do odświeżenia. Obsługuje interakcje dotykowe i zarządza stanem wewnętrznego wizualizatora odświeżania.
- RefreshVisualizer — hermetyzuje wizualizacje odświeżania, które są objaśnione w następnej sekcji.
Główną kontrolką jest RefreshContainer, którą umieszczasz jako obudowę wokół zawartości, którą użytkownik przeciąga, aby wywołać odświeżenie. Funkcja RefreshContainer działa tylko z obsługą dotykową, dlatego zalecamy również korzystanie z przycisku odświeżania dla użytkowników, którzy nie mają interfejsu dotykowego. Przycisk odświeżania można umieścić w odpowiedniej lokalizacji w aplikacji na pasku poleceń lub w lokalizacji w pobliżu odświeżonego obszaru.
Odświeżanie wizualizacji
Domyślna wizualizacja odświeżania to okrągły wskaźnik postępu, który służy do informowania o rozpoczęciu odświeżania i śledzeniu jego postępu po zainicjowaniu. Wizualizator odświeżania ma 5 stanów.
Odległość, na jaką użytkownik musi ściągnąć listę, aby zainicjować odświeżanie, jest nazywana progiem . Wizualizator Stan jest określany przez stan przeciążenia w odniesieniu do tego progu. Możliwe wartości znajdują się w wyliczeniu RefreshVisualizerState.
Bezczynny
Domyślny stan wizualizatora to bezwładny. Użytkownik nie wchodzi w interakcję z aplikacją RefreshContainer za pomocą dotyku i nie trwa odświeżanie.
Wizualnie nie widać śladów funkcji wizualizacji odświeżania.
Interakcja
Gdy użytkownik ściąga listę w kierunku określonym przez właściwość PullDirection i przed osiągnięciem progu, wizualizator znajduje się w stanie Interakcja.
Jeśli użytkownik zwolni kontrolkę w tym stanie, kontrolka powróci do bezczynności.
przed progiem ściągania do odświeżenia
Wizualnie ikona jest wyświetlana jako wyłączona (60% nieprzezroczystości). Ponadto ikona obraca się o pełny obrót podczas przewijania.
Jeśli użytkownik ściągnie listę przez próg, wizualizator przechodzi z Interakcja do Oczekiwanie.
Wizualnie ikona zmienia przezroczystość na 100% i pulsuje, zwiększając rozmiar do 150%, a następnie wraca do rozmiaru 100% podczas przejścia.
Oczekujące
Gdy użytkownik przeciągnął listę poza próg, wizualizator znajduje się w stanie Oczekujące.
- Jeśli użytkownik przeniesie listę z powrotem powyżej progu bez jej zwolnienia, wraca do stanu Interakcja.
- Jeśli użytkownik zwolni listę, zostanie zainicjowane żądanie odświeżania i przejdzie do stanu Odświeżanie.
Wizualnie ikona ma rozmiar 100 i przezroczystość%. W tym stanie ikona nadal przesuwa się w dół podczas przewijania, ale przestaje się obracać.
Orzeźwiające
Gdy użytkownik zwolni wizualizator po przekroczeniu progu, znajduje się w stanie Odświeżanie.
Po wprowadzeniu tego stanu jest zgłaszane zdarzenie RefreshRequested. Jest to sygnał uruchomienia odświeżania zawartości aplikacji. Argumenty zdarzenia (RefreshRequestedEventArgs) zawierają obiekt Odroczenia, który należy uchwycić w procedurze obsługi zdarzenia. Następnie należy oznaczyć odroczenie jako ukończone po zakończeniu wykonywania odświeżania kodu.
Po zakończeniu odświeżania wizualizator powraca do stanu bezczynności.
Wizualnie ikona powraca do lokalizacji progowej i obraca się przez czas trwania odświeżania. To kręcenie się służy do pokazywania postępu odświeżania i jest zastępowane animacją nadchodzącej zawartości.
Podglądanie
Gdy użytkownik przeciąga w kierunku odświeżania z pozycji początkowej, w której odświeżanie jest niedozwolone, wizualizator przechodzi w stan Podgląd. Zazwyczaj dzieje się tak, gdy ScrollViewer nie znajduje się w pozycji 0, gdy użytkownik zacznie przeciągać.
- Jeśli użytkownik zwolni kontrolkę w tym stanie, kontrolka powróci do bezczynności.
Kierunek ściągania
Domyślnie użytkownik ściąga listę od góry do dołu, aby zainicjować odświeżanie. Jeśli masz listę lub siatkę z inną orientacją, zmień kierunek ściągania kontenera odświeżania, aby był zgodny.
Właściwość PullDirection przyjmuje jedną z następujących wartości RefreshPullDirection: BottomToTop, TopToBottom, RightToLeftlub LeftToRight.
Po zmianie kierunku ściągnięcia pozycja początkowa pokrętła postępu wizualizatora automatycznie obraca się tak, aby strzałka zaczynała się w odpowiedniej pozycji dla kierunku ściągania. W razie potrzeby możesz zmienić właściwość RefreshVisualizer.Orientation, aby zastąpić zachowanie automatyczne. W większości przypadków zalecamy pozostawienie wartości domyślnej Auto.
Implementowanie ściągania do odświeżania
- ważne interfejsy programistyczne API: RefreshContainer, RefreshVisualizer
Aplikacja z galerii WinUI 3 zawiera interaktywne przykłady większości kontrolek, funkcji i funkcji interfejsu WinUI 3. Pobierz aplikację ze sklepu Microsoft Store lub pobierz kod źródłowy w witrynie GitHub
Aby dodać funkcje ściągania do odświeżenia do listy, należy wykonać kilka kroków.
- Opakuj listę w kontrolce RefreshContainer.
- Obsługa zdarzenia RefreshRequested w celu odświeżenia zawartości.
- Opcjonalnie zainicjuj odświeżanie, wywołując RequestRefresh (na przykład za pomocą kliknięcia przycisku).
Notatka
Możesz utworzyć wystąpienie klasy RefreshVisualizer samodzielnie. Zalecamy jednak umieszczanie zawartości w elemencie RefreshContainer i użycie klasy RefreshVisualizer dostarczonej przez właściwość RefreshContainer.Visualizer, nawet w przypadku scenariuszy bezdotykowych. W tym artykule przyjęto założenie, że wizualizator jest zawsze uzyskiwany z kontenera odświeżania.
Dla wygody, dodatkowo użyj elementów RequestRefresh i RefreshRequested kontenera.
refreshContainer.RequestRefresh()
jest odpowiednikiem refreshContainer.Visualizer.RequestRefresh()
i zarówno jedno, jak i drugie spowoduje wywołanie zarówno zdarzenia RefreshContainer.RefreshRequested, jak i zdarzenia RefreshVisualizer.RefreshRequested.
Żądanie odświeżenia
Kontener odświeżania obsługuje interakcje dotykowe, aby umożliwić użytkownikowi odświeżanie zawartości za pomocą dotyku. Zalecamy zapewnienie innych przystępnych cenowo interfejsów innych niż dotykowe, takich jak przycisk odświeżania lub sterowanie głosem.
Aby zainicjować odświeżanie, wywołaj metodę RequestRefresh.
// See the Examples section for the full code.
private void RefreshButtonClick(object sender, RoutedEventArgs e)
{
RefreshContainer.RequestRefresh();
}
Gdy wywołujesz metodę RequestRefresh, stan wizualizatora przechodzi bezpośrednio z stanu bezczynności do stanu odświeżania.
Obsługa żądania odświeżania
Aby uzyskać świeżą zawartość, gdy jest to potrzebne, obsłuż zdarzenie RefreshRequested. W procedurze obsługi zdarzeń będziesz potrzebować kodu specyficznego dla aplikacji, aby uzyskać świeżą zawartość.
Zdarzenie args (RefreshRequestedEventArgs) zawiera obiekt odroczenia. Uzyskaj uchwyt do odroczenia w obsłudze zdarzenia. Następnie oznacz odroczenie jako zakończone, gdy kod, który wykonuje odświeżenie, zostanie zakończony.
// 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();
}
}
Reagowanie na zmiany stanu
W razie potrzeby możesz reagować na zmiany stanu wizualizatora. Aby na przykład zapobiec wielu żądaniom odświeżania, można wyłączyć przycisk odświeżania podczas odświeżania wizualizatora.
// 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;
}
}
Korzystanie z programu ScrollViewer w module RefreshContainer
Notatka
Zawartość elementu RefreshContainer musi być kontrolką przewijaną, taką jak ScrollViewer, GridView, ListView itp. Ustawienie wartości Content na kontrolkę Grid spowoduje niezdefiniowane zachowanie.
W tym przykładzie pokazano, jak używać funkcji "pociągnij, aby odświeżyć" w kontrolce przewijania.
<RefreshContainer>
<ScrollViewer VerticalScrollMode="Enabled"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<!-- Scrollviewer content -->
</ScrollViewer>
</RefreshContainer>
Dodawanie funkcji pull-to-refresh do elementu ListView
W tym przykładzie pokazano, jak używać funkcji pull-to-refresh z widokiem listy.
<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 i WinUI 2
Ważny
Informacje i przykłady przedstawione w tym artykule są zoptymalizowane dla aplikacji korzystających z zestawu Windows App SDK i WinUI 3, ale są ogólnie stosowalne do aplikacji platformy UWP korzystających z interfejsu WinUI 2. Zobacz dokumentację interfejsu API platformy UWP, aby uzyskać informacje i przykłady dotyczące platformy.
Ta sekcja zawiera informacje potrzebne do używania kontrolki w aplikacji platformy UWP lub WinUI 2.
Kontrolki odświeżania dla aplikacji UWP systemu Windows są uwzględniane w WinUI 2. Aby uzyskać więcej informacji, w tym instrukcje dotyczące instalacji, zobacz WinUI 2. API dla tej kontrolki istnieją zarówno w przestrzeniach nazw Windows.UI.Xaml.Controls (UWP), jak i Microsoft.UI.Xaml.Controls (WinUI).
- interfejsy API platformy UWP:RefreshContainer, RefreshVisualizer
- API WinUI 2:RefreshContainer, RefreshVisualizer
- Otwórz aplikację Galerii WinUI 2 i zobacz PullToRefresh w akcji. Aplikacja z galerii WinUI 2 zawiera interaktywne przykłady większości kontrolek, funkcji i funkcji winUI 2. Pobierz aplikację ze sklepu Microsoft Store lub pobierz kod źródłowy w witrynie GitHub.
Zalecamy użycie najnowszych WinUI 2, aby mieć dostęp do najnowszych stylów, szablonów i funkcji dla wszystkich elementów sterujących.
Aby użyć kodu w tym artykule z WinUI 2, użyj aliasu w XAML (używamy "muxc
") do reprezentowania bibliotek Windows UI, które są uwzględnione w projekcie. Aby uzyskać więcej informacji, zobacz Rozpoczynanie pracy z interfejsem WinUI 2.
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:RefreshContainer />
Powiązane artykuły
- Interakcje dotykowe
- widok listy i widok siatki
- kontenery i szablony elementów
- animacje wyrażeń