Xamarin.Forms 中ListView實現到底載入更多
阿新 • • 發佈:2018-11-19
Xamarin.Forms 中ListView實現到底載入更多
在移動應用開發中,為了更好的使用者體驗,ListView控制元件的分頁效果通常是利用ListView到底載入來實現。
在Xamarin.Forms中ListView如何實現到底載入呢?
通過利用ListView的ItemAppearing來判斷最後一條資料是否展示出來,如果已經展示那麼說明ListView已經滾動到底部了。
來看看完整程式碼示例:
public class LoadMoreListView : ListView { private readonly StackLayout LoadingContent; private readonly StackLayout LoadMoreContent; private readonly StackLayout NoDataContent; public LoadMoreListView() : base(ListViewCachingStrategy.RecycleElement) { Xamarin.Forms.PlatformConfiguration.iOSSpecific.ListView.SetSeparatorStyle(this, Xamarin.Forms.PlatformConfiguration.iOSSpecific.SeparatorStyle.FullWidth); LoadingContent = CreateFooter("正在載入中...",true); LoadMoreContent = CreateFooter("上拉載入更多",false); NoDataContent = CreateFooter("已載入全部資料",false); ItemAppearing += LoadMoreListView_ItemAppearing; } private void LoadMoreListView_ItemAppearing(object sender, ItemVisibilityEventArgs e) { if (ItemsSource is IList items && e.Item == items[items.Count - 1]) { if (CanLoadMore && LoadStatus == LoadMoreStatus.StatusHasData) { if (CanLoadMore && (LoadMoreCommand?.CanExecute(null) == true)) LoadMoreCommand.Execute(null); } } } private StackLayout CreateFooterContent(string content,bool indicator = false) { var item = new StackLayout { Orientation = StackOrientation.Horizontal, HeightRequest = 50, VerticalOptions = LayoutOptions.CenterAndExpand, HorizontalOptions = LayoutOptions.CenterAndExpand, }; if(indicator) { try { item.Children.Add(new ActivityIndicator { IsRunning = true, WidthRequest = 20, HeightRequest = 20, VerticalOptions = LayoutOptions.CenterAndExpand }); } catch(Exception e) { Debug.WriteLine(e.Message); } } item.Children.Add(new Label { Text = content, VerticalOptions = LayoutOptions.CenterAndExpand }); return item; } private StackLayout CreateFooter(string content,bool hasIndicator) { var item = new StackLayout { Orientation = StackOrientation.Horizontal, HeightRequest = 50, }; var contentStack = CreateFooterContent(content,hasIndicator); item.Children.Add(contentStack); return item; } public static readonly BindableProperty LoadMoreCommandProperty = BindableProperty.Create(nameof(LoadMoreCommand), typeof(ICommand), typeof(LoadMoreListView), default(ICommand)); public ICommand LoadMoreCommand { get { return (ICommand)GetValue(LoadMoreCommandProperty); } set { SetValue(LoadMoreCommandProperty, value); } } public static readonly BindableProperty CanLoadMoreProperty = BindableProperty.Create(nameof(CanLoadMore), typeof(bool), typeof(LoadMoreListView), false); public bool CanLoadMore { get { return (bool)GetValue(CanLoadMoreProperty); } set { SetValue(CanLoadMoreProperty, value); } } public static readonly BindableProperty LoadStatusProperty = BindableProperty.Create(nameof(LoadStatus), typeof(LoadMoreStatus), typeof(LoadMoreListView), LoadMoreStatus.StatusDefault, propertyChanged: OnLoadStatusChanged); public LoadMoreStatus LoadStatus { get { return (LoadMoreStatus)GetValue(LoadStatusProperty); } set { SetValue(LoadStatusProperty, value); } } private static void OnLoadStatusChanged(BindableObject bindable, object oldValue, object newValue) { var lv = (LoadMoreListView)bindable; lv.NotifyLoadStatus((LoadMoreStatus)newValue); } public void NotifyLoadStatus(LoadMoreStatus loadStatus) { switch (loadStatus) { case LoadMoreStatus.StatusDefault: this.Footer = null; break; case LoadMoreStatus.StatusLoading: this.Footer = LoadingContent; break; case LoadMoreStatus.StatusHasData: this.Footer = LoadMoreContent; break; case LoadMoreStatus.StatusNoData: this.Footer = NoDataContent; break; default: this.Footer = null; break; } } } public enum LoadMoreStatus { StatusDefault = 0, StatusLoading = 1, StatusHasData = 2, StatusNoData = 3, }
以上程式碼簡單實現了一個到底載入功能,