前言
最近几天在研究上拉加载啊,下拉刷新啊什么的。然而坑爹的事情总是那么多。在xamarin.forms中,list自带的,并没有上拉加载的这个属性(难道当初他们封装方法时,就不会想到数据多了会咋整吗?)抱怨归抱怨,问题总是要解决的。
既然没有,那就自己写一个喽~
思路
我的思路是这样的,
什么是上拉刷新,那是不是就是说,在当前页面,看到最后一个item的时候,我需要加载一些新的数据,那我是不是可以写一个,只要出现了最后一个item我们就去刷新最新数据呢?
1 public class InfiniteListView : ListView 2 { 3 public static readonly BindableProperty LoadMoreCommandProperty = BindableProperty.Create(nameof(LoadMoreCommand), typeof(ICommand), typeof(InfiniteListView)); 4 public static readonly BindableProperty CanLoadMoreProperty = BindableProperty.Create(nameof(CanLoadMore), typeof(bool), typeof(InfiniteListView), true); 5 6 public ICommand LoadMoreCommand 7 { 8 get { return (ICommand)GetValue(LoadMoreCommandProperty); } 9 set { SetValue(LoadMoreCommandProperty, value); } 10 } 11 12 public bool CanLoadMore 13 { 14 get 15 { 16 return (bool)GetValue(CanLoadMoreProperty); 17 } 18 set 19 { 20 SetValue(CanLoadMoreProperty, value); 21 } 22 } 23 24 public InfiniteListView() 25 { 26 ItemAppearing += InfiniteListView_ItemAppearing; 27 } 28 29 private void InfiniteListView_ItemAppearing(object sender, ItemVisibilityEventArgs e) 30 { 31 if (!CanLoadMore) 32 { 33 return; 34 } 35 var items = ItemsSource as IList; 36 37 if (items != null && e.Item == items[items.Count - 1]) 38 { 39 if (LoadMoreCommand != null && LoadMoreCommand.CanExecute(null)) 40 LoadMoreCommand.Execute(null); 41 } 42 } 43 }
我们来继承listview,来实现它的ItemAppearing方法,然后再方法里一次次的判断有没有到最后一个item(说实话我不知道这对程序好不好,现在只是想到了实现),只要出现了最后一个item,就去执行绑定方法。
在页面绑定中,需要
<ContentPage xmlns:common="clr-namespace:XXX.Common;assembly=XXX" > <common:InfiniteListView CanLoadMore="{Binding IsLoadMore}" LoadMoreCommand="{Binding LoadMoreLogCommand}"> </common:InfiniteListView>
So。。其实是不是很简单?
简单测试了一下,发现了一个问题。就是我的list数据,有分组,一个list里面可能会有多个list,那最后一个item岂不是永远都是最外层的数据了?我把方法简单的改了一下
1 private void GroupInfiniteListView_ItemAppearing(object sender, ItemVisibilityEventArgs e) 2 { 3 if (!CanLoadMore) 4 { 5 return; 6 } 7 if (ItemsSource == null) 8 { 9 return; 10 } 11 var items = ItemsSource as IList; 12 var itemSourceCouunt = items.Count; 13 var iindex = 0; 14 IList lastData = ItemsSource as IList; 15 do 16 { 17 iindex++; 18 var lastItem = (items[items.Count - iindex]) as IList; 19 if (lastItem.Count > 0) 20 { 21 lastData = lastItem; 22 continue; 23 } 24 } while (itemSourceCouunt == iindex); 25 //foreach (var item in lastItem) 26 //{ 27 // if (item is IList) 28 // { 29 // var data = item as IList; 30 if (lastData.Count <= 0) 31 { 32 return; 33 } 34 if (lastData != null && e.Item == lastData[lastData.Count - 1]) 35 { 36 if (LoadMoreCommand != null && LoadMoreCommand.CanExecute(null)) 37 LoadMoreCommand.Execute(null); 38 // } 39 //} 40 //continue; 41 } 42 }
为了实现这个东西,其实费了我不少功夫(其实我真不知道xamarin.forms哪里省事省时间了)