让Xamarin.Forms中ListView支持上滑加载更多

衣明志 发表于 , 阅读 (3309)

Xamarin.Forms是Xamarin平台下的新框架,可以用一套UI代码,做多个平台的App,得到C#程序员们的喜爱,毕竟这代表着生产力大幅度提升。但是正如不完美的人类永远也做不成完美的事物来,xamarin.forms也有一些局限性(当然最新版已经支持在Forms中混合原生控件,解决了不少UI甚至UE上的问题)。例如,一个数据列表页面中,我们ListView很容易通过数据绑定手段实现列表,但是当数据足够多时就有问题了——通过webapi一次加载大量数据,既浪费流量也浪费时间,用户体验也很差(需要等待很久)。所以通常我们会让页面加载前面的一些数据,当用户将列表滑动到底部的时候再加载新的数据,这样循环往复可以不停的拉取新数据加载到列表中。很不幸,Xamarin.Forms的ListView控件默认并不直接支持这个功能。

控件的好处是复用,所以我们可以通过继承ListView,并稍微做一些改动调整来支持上滑到底部加载更多。代码如下:

public class InfiniteListView : ListView
{
    public static readonly BindableProperty LoadMoreCommandProperty = BindableProperty.Create(nameof(LoadMoreCommand), typeof(ICommand), typeof(InfiniteListView));

    public ICommand LoadMoreCommand
    {
        get { return (ICommand)GetValue(LoadMoreCommandProperty); }
        set { SetValue(LoadMoreCommandProperty, value); }
    }

    public InfiniteListView()
    {
        ItemAppearing += InfiniteListView_ItemAppearing;
    }

    private void InfiniteListView_ItemAppearing(object sender, ItemVisibilityEventArgs e)
    {
        var items = ItemsSource as IList;

        if (items != null && e.Item == items[items.Count - 1])
        {
            if (LoadMoreCommand != null && LoadMoreCommand.CanExecute(null))
                LoadMoreCommand.Execute(null);
        }
    }
}

在XAML中调用这个控件的方式如下:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:Controls="clr-namespace:Codenutz.XF.Controls;assembly=Codenutz.XF.Controls.InfiniteListView" 
    x:Class="Codenutz.XF.InfiniteListView.Shared.View.InfiniteListViewSampleView" 
    Title="{Binding Title}">

    <Controls:InfiniteListView 
        ItemsSource="{Binding MarvelCharacters}" 
        SelectedItem="{Binding SelectedCharacter}" 
        LoadMoreCommand="{Binding LoadCharactersCommand}">
    </Controls:InfiniteListView>

</ContentPage>

原理很简单,就是当ListView的最后一个Item显示在屏幕上时,执行加载更多命令(LoadMoreCommand)。而我们在这个命令中获取下一页数据并填充到ListView的绑定中即可,尤其当你用MVVM模式开发App时,这会让你很爽。你试试看就知道了。

ListView控件在Xamarin.Forms的App中,还有不少局限,尤其是面对国内的复杂UI设计需求时,经常显得有点乏力,如何应对这些问题,我将在后续的文章中跟大家一起探讨。

特别声明: 本文中的控件代码并非老衣原创,而是出自http://www.codenutz.com/lac09-xamarin-forms-infinite-scrolling-listview/

2 条评论
临冰听雪
临冰听雪 2017-10-09 11:33
当数据为空的时候,listview会一遍又一遍,不停的执行LoadMoreCommand,请问这个有办法处理一下嘛?
临冰听雪
临冰听雪 2017-10-09 11:50
而且有一个问题,它记录的最后一个itam永远都是第一次加载出来的itam,而不是最新的那个