UWP的一种下拉刷新实现

原文:UWP的一种下拉刷新实现

简介

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

通过下拉刷新这一机制,可以让移动端的界面设计变得更加简单,更符合广大用户的使用习惯。

 

NEW github链接:https://github.com/MS-UAP/PullToRefresh.UWP

该组件的nuget链接:https://www.nuget.org/packages/PullToRefresh.UWP

 

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

  • 支持自定义下拉头部,包括及时显示下拉进度,分辨率较高。
  • 用于ListView时,支持UI虚拟化和增量加载,不影响诸如ListView.Header等属性。

 

基本使用

使用效果如图:

只需要简单的:

<pr:PullToRefreshBox x:Name="pr" RefreshInvoked="PullToRefreshBox_RefreshInvoked">
    <ListView x:Name="lv" ItemTemplate="{StaticResource ColorfulRectangle}" />
</pr:PullToRefreshBox>

这是默认的效果。用户只需要订阅 RefreshInvoked 事件即可。

该事件类型为:TypedEventHandler<DependencyObject, object>,第一个参数sender为PullToRefreshBox的Content,第二个参数总是null。

 

更多设置

我们的下拉刷新控件提供更多设置可供开发者自定义其表现。

  • double RefreshThreshold {get;set;} :设置触发刷新的阈值,即有效下拉距离。
  • DataTemplate TopIndicatorTemplate {get;set;} :自定义下拉头部模板。这是一个DataTemplate,其DataContext只是一个double值,表示相对于下拉阈值的百分比(可以超过100%)。而该模板本身会决定可用的下拉大小。

 同时,我们还提供了一个PullRefreshProgressControl控件,方便开发者进行简单的头部定制。

该控件提供两个VisualState:Normal和ReleaseToRefresh,表示下拉过程中的两种状态(未到达刷新阈值,和已到达阈值)。

通过定义PullRefreshProgressControl.Template可以使用它(同样也要设定一下PullToRefreshBox.TopIndicatorTemplate,并且对PullRefreshProgressControl.Progress属性进行绑定)。

 

接下来为大家展示一下简单的定制效果:

相关代码如下:

<Grid>
    <pr:PullToRefreshBox RefreshInvoked="pr_RefreshInvoked">
        <pr:PullToRefreshBox.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:PullToRefreshBox.TopIndicatorTemplate>

        <ListView x:Name="ic">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalAlignment" Value="Center" />
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Rectangle Width="100" Height="200">
                        <Rectangle.Fill>
                            <SolidColorBrush Color="{Binding}" />
                        </Rectangle.Fill>
                    </Rectangle>
                </DataTemplate>
            </ListView.ItemTemplate>

        </ListView>
    </pr:PullToRefreshBox>
</Grid>

 

如果想要更加复杂的效果,则需要完全自定义PullToRefreshBox.TopIndicatorTemplate。

 

实现原理

采用外部嵌套ScrollViewer的方式实现。同时监控ScrollViewer的大小变化,以调整Content(即PullToRefreshBox.Content)的大小。

同时在下拉发生后,通过DirectManipulationCompleted事件,确定松开手指的时刻,并将下拉头部滚出ScrollViewer的可视区域。

在ScrollViewer.ViewChanged事件中计算下拉距离,以实现分辨率较高的进度绑定。

 

已知问题

  • 用于StackPanel,Canvas这类有无限大空间的控件 且不指定PullToRefreshBox的具体大小时,其大小会恒定不变,而不会随Content大小变化而变化。

 

该组件的nuget链接:https://www.nuget.org/packages/PullToRefresh.UWP

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

 

感谢 h82258652 提出的意见!

时间: 2024-09-27 00:19:02

UWP的一种下拉刷新实现的相关文章

懒人必备:多种下拉刷新,上拉加载更多以及配置自定义头部广告位库

简介 开发者使用 BGARefreshLayout-Android 可以对各种控件实现多种下拉刷新效果.上拉加载更多以及配置自定义头部广告位. 常见问题-加载更多视图无法显示. 1.BGARefreshLayout 的直接子控件的高度请使用 android:layout_height="0dp" 和 android:layout_weight="1" <cn.bingoogolapple.refreshlayout.BGARefreshLayout xmlns

UWP开发入门(七)——下拉刷新

原文:UWP开发入门(七)--下拉刷新 本篇意在给这几天Win10 Mobile负面新闻不断的某软洗地,想要证明实现一个简单的下拉刷新并不困难.UWP开发更大的困难在于懒惰,缺乏学习的意愿.而不是"某软连下拉刷新控件都没有"这样的想法. 之前我也没有进行过下拉刷新的研究.于是先去google了几篇blog学习了一下,然后再看了某软官方的Sample.(同学们啊官方有下拉刷新的Sample啊!就在Git上啊!不要钱无门槛啊!)学习之后发现实现的方式大体分为两类. 一类是以某软Sample

布局-android 下拉刷新的实现类

问题描述 android 下拉刷新的实现类 求下拉刷新的实现(刷新的主体不单单是listview一种的,而是包含了图片,listvew等组合在一起的),怎么实现啊,求源码 解决方案 需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新:思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到ListView中,从而实现消息列表的展示.而下拉刷新要求给消息列表加一个头部,其中有图片(向上/向下箭头)和提示字样(下拉刷新/松开刷新),从而我们需要

网页用户体验设计:有趣的下拉刷新

文章描述:下拉刷新这一部分的细节设计,可以是传达产品价值.推广品牌理念的一个机会,精心做一些特别一点的设计,就可以让大家记住你.所以,我们可以在以后的产品设计中,把握好产品大方向的同时,兼顾一些这种小细节设计,把我们的品牌元素和产品价值的东西能够成为产品的一些 5月22日,Twitter正式宣布获得了下拉刷新的技术专利,这项专利是在一年前提出的,虽然公司一再说明此项专利只用于保护自己,不会用来发起诉讼,但无疑这还是对行业来说是一个威胁. 下拉刷新这个操作最早由Tweetie创始人洛伦•布里切特(

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

最近项目中需要用到ListView下拉刷新的功能,一开始想图省事,在网上直接找一个现成的,可是尝试了 网上多个版本的下拉刷新之后发现效果都不怎么理想.有些是因为功能不完整或有Bug,有些是因为使用起来 太复杂,十全十美的还真没找到.因此我也是放弃了在网上找现成代码的想法,自己花功夫编写了一种非常 简单的下拉刷新实现方案,现在拿出来和大家分享一下.相信在阅读完本篇文章之后,大家都可以在自己的 项目中一分钟引入下拉刷新功能. 首先讲一下实现原理.这里我们将采取的方案是使用组合View的方 式,先自定

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

以下是我自己花功夫编写了一种非常简单的下拉刷新实现方案,现在拿出来和大家分享一下.相信在阅读完本篇文章之后,大家都可以在自己的项目中一分钟引入下拉刷新功能   最近项目中需要用到ListView下拉刷新的功能,一开始想图省事,在网上直接找一个现成的,可是尝试了网上多个版本的下拉刷新之后发现效果都不 怎么理想.有些是因为功能不完整或有Bug,有些是因为使用起来太复杂,十全十美的还真没找到.因此我也是放弃了在网上找现成代码的想法,自己花功夫编写 了一种非常简单的下拉刷新实现方案,现在拿出来和大家分享

交互设计:有趣的下拉刷新

下拉刷新这个操作最早由Tweetie创始人洛伦•布里切特(Loren Brichter)发明,到现在已经非常广泛地在各种应用中使用,Sparrow.Facebook.新浪微博.甚至是iOS原生系统也都在使用这种方 式.有理论认为,下拉刷新是一种适用于按照从新到旧的时间顺序排列feeds的应用,在这种应用场景中看完旧的内容时,用户会很自然地下拉查找更新的内 容,因此下拉刷新就显得非常合理.随着下拉刷新这种方式的不断演变,下拉刷新已经跳出基础功能,成为一种表现品牌.表现设计感的元素,本文主要介绍几款

Android下拉刷新控件PullToRefresh实例解析_Android

Android中很多时候都会用到上下拉刷新,这是一个很常用的功能,Android的v4包中也为我们提供了一种原生的下拉刷新控件--SwipeRefreshLayout,可以用它实现一个简洁的刷新效果,但今天我们的主角并不是它,而是一个很火的第三方的上下拉刷新控件--PullToRefresh.PullToRefresh包括PullToRefreshScrollView.PullToRefreshListView.PullToRefreshGridView等等很多为我们提供的控件,我们可以在xml

Android:下拉刷新+加载更多+滑动删除实例讲解_Android

         小伙伴们在逛淘宝或者是各种app上,都可以看到这样的功能,下拉刷新和加载更多以及滑动删除,刷新,指刷洗之后使之变新,比喻突破旧的而创造出新的,比如在手机上浏览新闻的时候,使用下拉刷新的功能,我们可以第一时间掌握最新消息,加载更多是什么nie,简单来说就是在网页上逛淘宝的时候,我们可以点击下一页来满足我们更多的需求,但是在手机端就不一样了,没有上下页,怎么办nie,方法总比困难多,细心的小伙伴可能会发现,在手机端中,有加载更多来满足我们的要求,其实加载更多也是分页的一种体现.小伙