本篇意在給這幾天Win10 Mobile負面新聞不斷的某軟洗地,想要證明實現一個簡單的下拉刷新並不困難。UWP開發更大的困難在於懶惰,缺乏學習的意願。而不是“某軟連下拉刷新控制項都沒有”這樣的想法。 之前我也沒有進行過下拉刷新的研究。於是先去google了幾篇blog學習了一下,然後再看了某軟官方的S
本篇意在給這幾天Win10 Mobile負面新聞不斷的某軟洗地,想要證明實現一個簡單的下拉刷新並不困難。UWP開發更大的困難在於懶惰,缺乏學習的意願。而不是“某軟連下拉刷新控制項都沒有”這樣的想法。
之前我也沒有進行過下拉刷新的研究。於是先去google了幾篇blog學習了一下,然後再看了某軟官方的Sample。(同學們啊官方有下拉刷新的Sample啊!就在Git上啊!不要錢無門檻啊!)學習之後發現實現的方式大體分為兩類。
一類是以某軟Sample和博客園MS-UAP封裝的PullToRefreshBox為代表,將一片“釋放刷新”區域和一個ListView上下排列放置到一個ScrollView中。初始通過向下滾動ScrollView將“釋放刷新”區域上移至不可見,在每次向上滾動顯示“釋放刷新”區域時,觸發ScrollView的ViewChanged事件來進行載入新數據。完成新數據載入後,再次將“釋放刷新”區域上移隱藏。
另一類是通過附加屬性來獲取ListView內部的ScrollView,並檢測內部ScrollView的相關Manpulation事件來實現數據刷新。
考慮到附加屬性稍稍超出入門範圍,且第一類代碼可以寫得較為簡單。故採用ScrollView嵌套的方法,給出一個極簡的下拉刷新實現,雖並不能應對所有的需求,但考慮到30行不到的代碼量,絕對你值得擁有!
首先是XAML的代碼,平淡無奇沒有任何高深的技巧:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <ScrollViewer x:Name="scrollViewer" Loaded="scrollViewer_Loaded" ViewChanged="scrollViewer_ViewChanged"> <StackPanel Orientation="Vertical"> <ProgressRing IsActive="{x:Bind IsPullRefresh,Mode=OneWay}" Height="30"></ProgressRing> <ListView x:Name="list" ItemsSource="{x:Bind Items}" ></ListView> </StackPanel> </ScrollViewer> </Grid>
再來看cs文件。首先是Items和IsPullRefresh屬性的定義,前者是ListView中的數據集,後者Binding到ProgressRing的IsActive屬性,這裡略過不表。
值得註意的僅有scrollViewer_Loaded和scrollViewer_ViewChanged兩個方法。scrollViewer的Load方法里,我們在初始狀態下將ScrollViewer向上滾動了30個px,正好將ProgressRing隱藏了起來。然後是scrollViewer_ViewChanged方法,IsIntermediate屬性指出滑動是否還在進行中,如果不是並且到達頂部了,就去載入新的數據,同時控制ProgressRing的菊花轉圈圈。最後,再將ScrollViewer向上滾動30px藏起ProgressRing。
public sealed partial class MainPage : Page, INotifyPropertyChanged { public ObservableCollection<object> Items { get; set; } public bool IsPullRefresh { get { return _isPullRefresh; } set { _isPullRefresh = value; OnPropertyChanged(nameof(IsPullRefresh)); } } bool _isPullRefresh = false; public MainPage() { this.InitializeComponent(); Items = new ObservableCollection<object>(); for (int i = 0; i < 40; i++) { Items.Add(i); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string name) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } private void scrollViewer_Loaded(object sender, RoutedEventArgs e) { scrollViewer.ChangeView(null, 30, null); } private async void scrollViewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) { var sv = sender as ScrollViewer; if (!e.IsIntermediate) { if (sv.VerticalOffset == 0.0) { IsPullRefresh = true; await Task.Delay(2000); for (int i = 0; i < 5; i++) { Items.Insert(0, i); } sv.ChangeView(null, 30, null); } IsPullRefresh = false; } } }
打完收工,是不是覺得挺簡單的?UWP開發即是如此,困難確實有,經驗的確沒有。跟相對成熟的iOS和Android開發相比,是需要更多的汗水和努力。但是微軟是否要倒了?微軟技術又是否沒前途?Windows 10是否廢品?有空在網上搜這種沒有卵用的東西,不如多多學習。
繼續打廣告,這種ScrollViewer嵌套ListView的方式呢,確實可以解決問題。但偶爾也會發現和ListView控制項自身的ScrollViewer滑動衝突,以及不能精確定位ListViewItem等問題。那麼如果想要更加精進的話?記得看俺下一篇哦,隨手點個贊吧……嘿嘿嘿……
Microsoft/Windows-universal-samples