我们最近实现了一个在UWP中使用的下拉刷新功能,以满足用户的需求,因为这是下拉刷新是一种常见的操作方式,而UWP本身并不提供这一机制。
nuget链接:https://www.nuget.org/packages/PullToRefresh.UWP
并且,我们实现的这一下拉刷新功能,具有以下优点:
- 支持自定义下拉头部,包括及时显示下拉进度,分辨率较高。
- 通过ScrollViewer实现,扩展性比较好,且操作界面和ScrollViewer一致,DependencyProperty也是bindable的。
- 用于ListView时,不影响UI虚拟化的效果。
使用效果如图:
相关代码如下:
<Grid> <pr:PullToRefreshListView x:Name="ic" RefreshInvoked="ic_RefreshInvoked"> <pr:PullToRefreshListView.TopIndicatorTemplate> <DataTemplate> <Grid Background="LightBlue" Height="130" Width="200"> <pr:PullRefreshProgressControl Progress="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Bottom"> <pr:PullRefreshProgressControl.Template> <ControlTemplate> <Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="VisualStateGroup"> <VisualState x:Name="Normal" /> <VisualState x:Name="ReleaseToRefresh"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txt" Storyboard.TargetProperty="Text"> <DiscreteObjectKeyFrame KeyTime="0" Value="释放刷新" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> </Grid.RowDefinitions> <TextBlock x:Name="txt" Text="下拉刷新" Grid.Row="1" FontSize="20" HorizontalAlignment="Center" /> <TextBlock Text="{Binding}" FontSize="24" Foreground="Gray" HorizontalAlignment="Center" /> </Grid> </ControlTemplate> </pr:PullRefreshProgressControl.Template> </pr:PullRefreshProgressControl> </Grid> </DataTemplate> </pr:PullToRefreshListView.TopIndicatorTemplate> <pr:PullToRefreshListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="HorizontalAlignment" Value="Center" /> </Style> </pr:PullToRefreshListView.ItemContainerStyle> <pr:PullToRefreshListView.ItemTemplate> <DataTemplate> <Rectangle Width="100" Height="200"> <Rectangle.Fill> <SolidColorBrush Color="{Binding}" /> </Rectangle.Fill> </Rectangle> </DataTemplate> </pr:PullToRefreshListView.ItemTemplate> </pr:PullToRefreshListView> </Grid>
可以看到,只要在<pr:PullToRefreshListView.TopIndicatorTemplate>中定义DataTemplate作为下拉头部模板即可,Binding是指触发刷新的下拉百分比。
刷新函数通过PullToRefreshListView.RefreshInvoked函数进行。
下拉阈值通过PullToRefreshListView.RefreshThreshold设置,类型是double,表示像素。不过Binding到头部的是百分比。
PullRefreshProgressControl是自带的一种头部控件,可以为它设置Template哦。它具有一个VisualState:ReleaseToRefresh,表示已触发刷新,松开就可以刷新了(推回去就不刷新)。
当然可以完全自定义下拉头部。
如果只需要基本的ScrollViewer,可以将pr:PullToRefreshListView替换成pr:PullToRefreshScrollViewer,具有同样的操作界面。
将其他ControlTemplate中的ScrollViewer替换成pr:PullToRefreshScrollViewer,也能将下拉刷新集成在别的控件里:
<ControlTemplate TargetType="local:PullToRefreshListView"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <local:PullToRefreshScrollViewer x:Name="PullToRefreshScrollViewer" AutomationProperties.AccessibilityView="Raw" ScrollViewer.BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" ScrollViewer.HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" ScrollViewer.HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" ScrollViewer.IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" ScrollViewer.IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" ScrollViewer.IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" ScrollViewer.IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" ScrollViewer.IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" TabNavigation="{TemplateBinding TabNavigation}" ScrollViewer.VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" ScrollViewer.VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ScrollViewer.ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}" TopIndicatorTemplate="{TemplateBinding TopIndicatorTemplate}" RefreshThreshold="{TemplateBinding RefreshThreshold}"> <ItemsPresenter FooterTransitions="{TemplateBinding FooterTransitions}" FooterTemplate="{TemplateBinding FooterTemplate}" Footer="{TemplateBinding Footer}" HeaderTemplate="{TemplateBinding HeaderTemplate}" Header="{TemplateBinding Header}" HeaderTransitions="{TemplateBinding HeaderTransitions}" Padding="{TemplateBinding Padding}" /> </local:PullToRefreshScrollViewer> </Border> </ControlTemplate>
对于ScrollViewer提供的Attached DependencyProperty,pr:PullToRefreshScrollViewer继续沿用,以保持外层控件的原有设定。binding时需要注意。
已知问题
- PullToRefreshListView不具有自动增量加载的效果
- PullToRefreshScrollViewer的部分属性,如BringIntoViewOnFocusChange无效。
nuget链接:https://www.nuget.org/packages/PullToRefresh.UWP
如果大家在使用中遇到了什么问题,希望能向我们反馈,以使得我们的实现变得更好。