在win8中如何实现下拉刷新的功能
现在我以listview为例来讲述下拉刷新的功能!
在xaml中设置listview一定要设置一个这样的属性,IsSwipeEnabled=false,然后再listview控件的前面要布局下拉刷新的图标及提示,在listview控件的后面也要布局上拉时的提示信息。
现在我将个人的布局展现出来,仅供大家参考!
<Grid Name="layoutCtlRoot" MinWidth="240"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <Border Name="recRefresh" Height="0" Margin="0" MaxHeight="800" VerticalAlignment="Bottom"> <Grid> <Grid Margin="10" VerticalAlignment="Bottom"> <Grid.ColumnDefinitions> <ColumnDefinition Width="64"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Center"> <Image Name="imgArrow" Style="{StaticResource ProgressArrowStyle}"> <Image.RenderTransform> <RotateTransform x:Name="imageRotateTransform" Angle="0"/> </Image.RenderTransform> </Image> <ProgressRing Name="prgRefresh" Style="{StaticResource ProgressRingStyle}"/> </StackPanel> <StackPanel VerticalAlignment="Bottom" Grid.Column="1"> <TextBlock Name="txtOperationTip" Style="{StaticResource TipsContentStyle}"/> <TextBlock Name="txtOperationTime" Style="{StaticResource TipsContentStyle}"/> </StackPanel> </Grid> <Border Background="#99999999" VerticalAlignment="Bottom" Height="1"/> </Grid> </Border> <ListView Name="ForumList" Grid.Row="1" IsSwipeEnabled="False" ItemContainerStyle="{StaticResource ListItemBaseStyle}"/> <Border Name="recLoad" Height="0" Grid.Row="2" MaxHeight="800"> <Grid VerticalAlignment="Top" Margin="0,10"> <Border Background="#99999999" VerticalAlignment="Top" Height="1"/> <StackPanel Name="splNextPageLoading" HorizontalAlignment="Center" Orientation="Horizontal" Visibility="Collapsed"> <ProgressRing Style="{StaticResource ProgressRingStyle}" Visibility="Visible"/> <TextBlock Text="正在加载…" Margin="13" Style="{StaticResource TipsContentStyle}"/> </StackPanel> </Grid> </Border> </Grid>
然后在后台就要实现下拉刷新的正真效果呢!
这里特别要指出的要注册这样一个事件, this.LayoutUpdated += ForumList_LayoutUpdated;不然就实现不了!
也要注册listview的触摸事件,例如:
this.ForumList.ManipulationStarted+=ForumList_ManipulationStarted;
this.ForumList.ManipulationDelta+=ForumList_ManipulationDelta;
this.ForumList.ManipulationCompleted+=ForumList_ManipulationCompleted;
思路就是这样的,现在我就讲后台的逻辑也给大家参考!
DispatcherTimer toptimer = new DispatcherTimer(); DispatcherTimer timer = new DispatcherTimer(); private ScrollViewer listViewScrollViewer; private double listviewItemHeight = -1; private int optLimitHeight = 96; private bool isInPrpcessing = false; private Point eventStartPoint; private double lastDeltaHandledY = 0; private ObservableCollection<dynamic> listDataItems = new ObservableCollection<dynamic>(); //移动开始位置 private Point moveStartPoint; //是否可以移动 private bool canMove = false; public ListPage() { this.InitializeComponent(); this.imgArrow.Source = new BitmapImage(new Uri(@"ms-appx:///Assets/pullrefresh_arrow.png",UriKind.RelativeOrAbsolute)); this.LayoutUpdated += ForumList_LayoutUpdated; this.recRefresh.SizeChanged+=recRefresh_SizeChanged; this.ForumList.ManipulationStarted+=ForumList_ManipulationStarted; this.ForumList.ManipulationDelta+=ForumList_ManipulationDelta; this.ForumList.ManipulationCompleted+=ForumList_ManipulationCompleted; //this.ForumList.SelectionChanged+=ForumList_SelectionChanged; }
private void ForumList_LayoutUpdated(object sender, object e) { if (this.Height.Equals(double.NaN) && this.Parent != null) { this.Height = ((Windows.UI.Xaml.FrameworkElement)(this.Parent)).ActualHeight; } if (listViewScrollViewer == null) { listViewScrollViewer = FindVisualElement<ScrollViewer>(VisualTreeHelper.GetParent(this)); listViewScrollViewer.ManipulationMode = ManipulationModes.All; } for (int i = 0; i < this.ForumList.Items.Count; i++) { ListViewItem item = this.ForumList.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem; if (item != null && item.ManipulationMode != ManipulationModes.All) { item.ManipulationMode = ManipulationModes.All; if (listviewItemHeight < 0) { listviewItemHeight = ((Windows.UI.Xaml.FrameworkElement)(item)).ActualHeight; } } } } private static T FindVisualElement<T>(DependencyObject container) where T : DependencyObject { Queue<DependencyObject> childQueue = new Queue<DependencyObject>(); childQueue.Enqueue(container); while (childQueue.Count > 0) { DependencyObject current = childQueue.Dequeue(); T result = current as T; if (result != null && result != container) { return result; } int childCount = VisualTreeHelper.GetChildrenCount(current); for (int childIndex = 0; childIndex < childCount; childIndex++) { childQueue.Enqueue(VisualTreeHelper.GetChild(current, childIndex)); } } return null; }
private void recRefresh_SizeChanged( object sender,SizeChangedEventArgs e) { if (e.NewSize.Height > this.optLimitHeight && !isInPrpcessing) { if (!this.txtOperationTip.Text.Equals("松开刷新…")) { this.txtOperationTip.Text = "松开刷新…"; this.ImgStoryBoard.Begin(); } } } private void ForumList_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e) { eventStartPoint = e.Position; lastDeltaHandledY = 0; if (!isInPrpcessing) { this.txtOperationTip.Text = "下拉刷新列表…"; } e.Handled = true; } private void ForumList_ManipulationDelta(object sender,ManipulationDeltaRoutedEventArgs e) { double offset = e.Cumulative.Translation.Y - lastDeltaHandledY; if (listViewScrollViewer.VerticalOffset < 3) { double height = recRefresh.Height + offset; recRefresh.Height = height > 0 ? height : 0; if (offset < 0 && recRefresh.Height <= 0) { //向上滑动且刷新Panel未显示时滚动条下移 listViewScrollViewer.ScrollToVerticalOffset(listViewScrollViewer.VerticalOffset-offset/listviewItemHeight); } } else if (listViewScrollViewer.VerticalOffset >= listViewScrollViewer.ScrollableHeight - 1) { double height = recLoad.Height - offset; recLoad.Height = height > 0 ? height : 0; if (offset > 0 && recLoad.Height <= 0) { listViewScrollViewer.ScrollToVerticalOffset(listViewScrollViewer.VerticalOffset - offset / listviewItemHeight); } } else { listViewScrollViewer.ScrollToVerticalOffset(listViewScrollViewer.VerticalOffset-offset/listviewItemHeight); } lastDeltaHandledY = e.Cumulative.Translation.Y; e.Handled = true; } private void ForumList_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e) { if (listViewScrollViewer != null) { double offset = listViewScrollViewer.VerticalOffset; double total = listViewScrollViewer.ScrollableHeight; if (offset <= 3 || offset > total - 2) { DoListItemsSwipe(); } } } /// <summary> /// 数据加载后是否可下拉刷新 /// </summary> public static readonly DependencyProperty RefreshableProperty = DependencyProperty.Register("Refreshable", typeof(bool), typeof(ListPage), new PropertyMetadata(true)); public bool Refreshable { get { return (bool)base.GetValue(RefreshableProperty); } set { base.SetValue(RefreshableProperty, value); if (!value) { this.imgArrow.Visibility = Windows.UI.Xaml.Visibility.Collapsed; this.prgRefresh.Visibility = Windows.UI.Xaml.Visibility.Collapsed; this.txtOperationTip.Visibility = Windows.UI.Xaml.Visibility.Collapsed; this.txtOperationTime.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } } } private void DoListItemsSwipe() { if (recRefresh.Height > 0) { if (recRefresh.Height > optLimitHeight && this.Refreshable) { recRefresh.Height = 96; imgArrow.Visibility = Visibility.Collapsed; prgRefresh.Visibility = Visibility.Visible; if (!this.isInPrpcessing) { System.Diagnostics.Debug.WriteLine(this.isInPrpcessing); DoListDataSourceRefresh(); } } else { recRefresh.Height = 0; } listViewScrollViewer.ScrollToVerticalOffset(2.05); } if (recLoad.Height > 0) { if (recLoad.Height > optLimitHeight) { recLoad.Height = 68; splNextPageLoading.Visibility = Visibility.Visible; if (!this.isInPrpcessing) { DoListDataLoadNextPage(); } } else { recLoad.Height = 0; } } } private void DoListDataSourceRefresh() { this.isInPrpcessing = true; this.txtOperationTip.Text = "加载数据中"; this.isInPrpcessing = false; this.recRefresh.Height = 0; this.imgArrow.Visibility = Windows.UI.Xaml.Visibility.Visible; this.prgRefresh.Visibility = Windows.UI.Xaml.Visibility.Collapsed; this.ImgStoryBoard.Begin(); //箭头复位 } private void DoListDataLoadNextPage() { this.recLoad.Height = 0; splNextPageLoading.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } public event SelectionChangedEventHandler SelectionChanged; private void ForumList_SelectionChanged( object sender,SelectionChangedEventArgs e) { SelectionChanged(sender,e); }
不积跬步,无以至千里!