转载

UWP的一种下拉刷新实现

我们最近实现了一个在UWP中使用的下拉刷新功能,以满足用户的需求,因为这是下拉刷新是一种常见的操作方式,而UWP本身并不提供这一机制。

nuget链接: https://www.nuget.org/packages/PullToRefresh.UWP

并且,我们实现的这一下拉刷新功能,具有以下优点:

  • 支持自定义下拉头部,包括及时显示下拉进度,分辨率较高。
  • 通过 ScrollViewer 实现,扩展性比较好,且操作界面和 ScrollViewer 一致, DependencyProperty 也是bindable的。
  • 用于 ListView 时,不影响UI虚拟化的效果。

使用效果如图:

UWP的一种下拉刷新实现

相关代码如下:

<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

如果大家在使用中遇到了什么问题,希望能向我们反馈,以使得我们的实现变得更好。

正文到此结束
Loading...