Xamarin.forms 以每结果十项为增量加载数据Xamarin表单
我试图构建一个请求,每次从服务器为每个请求加载10个项目。例如,当用户单击一个按钮,将其重定向到下一页时,我希望前10个项目首先显示,而对其他项目的请求则在后台进行。我该怎么做呢?我知道它是如何工作的,在服务器端,通过设置每个请求返回的最大数量和起始位置,但这是正确的方法吗?是的,这听起来是一个处理它的好方法。这通常称为数据的“分页” 让API处理要接收的数据“页面”的偏移量以及该页面要返回的最大项数(pagesize)。下面是一个如何为表单实现此功能的示例 ViewModel要实现的合同: ViewModel中的一个示例实现:Xamarin.forms 以每结果十项为增量加载数据Xamarin表单,xamarin.forms,Xamarin.forms,我试图构建一个请求,每次从服务器为每个请求加载10个项目。例如,当用户单击一个按钮,将其重定向到下一页时,我希望前10个项目首先显示,而对其他项目的请求则在后台进行。我该怎么做呢?我知道它是如何工作的,在服务器端,通过设置每个请求返回的最大数量和起始位置,但这是正确的方法吗?是的,这听起来是一个处理它的好方法。这通常称为数据的“分页” 让API处理要接收的数据“页面”的偏移量以及该页面要返回的最大项数(pagesize)。下面是一个如何为表单实现此功能的示例 ViewModel要实现的合同:
#region ISupportIncrementalLoading Implementation
public int PageSize { get; set; } = 10;
public bool HasMoreItems { get; set; }
public async Task LoadMoreItemsAsync()
{
await LoadMoreItemsCommand.ExecuteAsyncTask();
}
//...
#endregion
示例LoadMoreItemsCommand:
LoadMoreItemsCommand = new Command(async () =>
{
int fetchOffset = Requests.Count;
int fetchMax = PageSize;
// "Pagination" of your API request starting at the offset
// and getting a maximum of the `fetchMax` or "page size"
Results = await GetRequestsAsync(fetchOffset, fetchMax);
});
要在控件(如ListView
中自动支持此操作,可以自定义渲染器或“效果”来实现此操作。以下是一个删减的示例:
// Custom ListViewRenderer, iOS example
public class IncrementalListViewRenderer : ListViewRenderer
{
public IncrementalListViewRenderer()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
// Need to customize the source but not lose existing functionality so
// we need a copy of it to use
UITableViewSource defaultSource = Control.Source;
Control.Source = new IncrementalDataSource(Element as IncrementalListView, defaultSource);
}
}
class IncrementalDataSource : UITableViewSource
{
readonly UITableViewSource existingSource;
readonly IncrementalListView listView;
readonly ISupportIncrementalLoading incrementalLoading;
int lastPosition;
int preloadMargin = 5;
public IncrementalDataSource(IncrementalListView listView, UITableViewSource existingSource)
{
this.listView = listView;
this.existingSource = existingSource;
incrementalLoading = listView.BindingContext as ISupportIncrementalLoading;
lastPosition = 0;
LoadMoreItems();
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
int position = indexPath.Row;
var itemsSource = listView.ItemsSource as IList;
if (itemsSource != null)
{
int preloadIndex = Math.Max(itemsSource.Count - preloadMargin, 0);
if ((position > lastPosition || (position == itemsSource.Count - 1)) && (position >= preloadIndex))
{
lastPosition = position;
if(!incrementalLoading.IsLoading && incrementalLoading.HasMoreItems)
LoadMoreItems();
}
}
var cell = existingSource.GetCell(tableView, indexPath);
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
return cell;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
existingSource.RowSelected(tableView, indexPath);
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return existingSource.RowsInSection(tableview, section);
}
void LoadMoreItems()
{
// Note the use of Nito.AsyncEx lib
INotifyTaskCompletion taskCompletion = NotifyTaskCompletion.Create(LoadMoreItemsAsync());
}
public async Task LoadMoreItemsAsync()
{
await incrementalLoading.LoadMoreItemsAsync();
}
}
}
//自定义ListViewRenderer,iOS示例
公共类IncrementalListViewRenderer:ListViewRenderer
{
public IncrementalListViewRenderer()
{
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(控件!=null)
{
//需要自定义源代码,但不丢失现有功能,以便
//我们需要一份副本来使用
UITableViewSource defaultSource=Control.Source;
Control.Source=新的IncrementalDataSource(元素为IncrementalListView,defaultSource);
}
}
类IncrementalDataSource:UITableViewSource
{
只读UITableViewSource现有源;
只读递增列表视图列表视图;
只读支持递增加载递增加载;
最后位置;
int预加裕度=5;
公共增量数据源(增量列表视图列表视图,UITableViewSource现有源)
{
this.listView=listView;
this.existingSource=existingSource;
incrementalLoading=listView.BindingContext作为ISupportIncrementalLoading;
lastPosition=0;
loadmoreems();
}
公共覆盖UITableViewCell GetCell(UITableView tableView,NSIndexPath indexPath)
{
int position=indexPath.Row;
var itemsSource=listView.itemsSource作为IList;
如果(itemsSource!=null)
{
int preload index=Math.Max(itemsSource.Count-preload-margin,0);
if((position>lastPosition | | |(position==itemsSource.Count-1))&&(position>=preload index))
{
最后位置=位置;
如果(!incrementalLoading.IsLoading&&incrementalLoading.HasMoreItems)
loadmoreems();
}
}
var cell=existingSource.GetCell(tableView,indexPath);
cell.SelectionStyle=UITableViewCellSelectionStyle.None;
返回单元;
}
public override void RowSelected(UITableView tableView,NSIndexPath indexPath)
{
existingSource.RowSelected(tableView,indexPath);
}
公共覆盖第九行第九节(UITableView表格视图,第九节)
{
返回existingSource.RowsInSection(tableview,section);
}
void LoadMoreItems()
{
//请注意Nito.AsyncEx lib的使用
INotifyTaskCompletion taskCompletion=NotifyTaskCompletion.Create(LoadMoreItemsAsync());
}
公共异步任务LoadMoreItemsAsync()
{
等待incrementalLoading.LoadMoreItemsAsync();
}
}
}
这充分利用了插件的技术
// Custom ListViewRenderer, iOS example
public class IncrementalListViewRenderer : ListViewRenderer
{
public IncrementalListViewRenderer()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
// Need to customize the source but not lose existing functionality so
// we need a copy of it to use
UITableViewSource defaultSource = Control.Source;
Control.Source = new IncrementalDataSource(Element as IncrementalListView, defaultSource);
}
}
class IncrementalDataSource : UITableViewSource
{
readonly UITableViewSource existingSource;
readonly IncrementalListView listView;
readonly ISupportIncrementalLoading incrementalLoading;
int lastPosition;
int preloadMargin = 5;
public IncrementalDataSource(IncrementalListView listView, UITableViewSource existingSource)
{
this.listView = listView;
this.existingSource = existingSource;
incrementalLoading = listView.BindingContext as ISupportIncrementalLoading;
lastPosition = 0;
LoadMoreItems();
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
int position = indexPath.Row;
var itemsSource = listView.ItemsSource as IList;
if (itemsSource != null)
{
int preloadIndex = Math.Max(itemsSource.Count - preloadMargin, 0);
if ((position > lastPosition || (position == itemsSource.Count - 1)) && (position >= preloadIndex))
{
lastPosition = position;
if(!incrementalLoading.IsLoading && incrementalLoading.HasMoreItems)
LoadMoreItems();
}
}
var cell = existingSource.GetCell(tableView, indexPath);
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
return cell;
}
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
existingSource.RowSelected(tableView, indexPath);
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return existingSource.RowsInSection(tableview, section);
}
void LoadMoreItems()
{
// Note the use of Nito.AsyncEx lib
INotifyTaskCompletion taskCompletion = NotifyTaskCompletion.Create(LoadMoreItemsAsync());
}
public async Task LoadMoreItemsAsync()
{
await incrementalLoading.LoadMoreItemsAsync();
}
}
}