说明

在本博客中,学习如何在Xamarin.Forms应用程序中设计一个可扩展的无限滚动的ListView。这个无限滚动函数在默认的Xamarin.Forms不存在,因此我们需要为此添加插件。在这里我们需要知道无限滚动时如何工作的。首先,显示固定的数据。一旦用户滚动到末尾,我们可以在列表的末尾添加更多的数据,这样,列表就会不断滚动,直到数据结束。

让我们开始吧

第一步

创建一个新的Xamarin.Forms工程,打开Visual Studio,点击新建->项目->在对话框中选择移动应用(Xamarin.Forms),并点击下一步**

(未使用原文图片)

第二步

接下来,出现一个新的对话框,在这里给出应用程序和解决方案的名称,名字为:XFInfiniteScroll,然后点击创建



(未使用原文图片)

第三步

之后,在新的对话框窗口中,选择你的Xamarin.Forms应用模板类型和平台之后点击确定,在这里,我选择选项卡式模板和Android,iOS平台。因为这里选择空模板时,没有成功,改选用选项卡模板



(未使用原文图片)

第四步

在项目创建完成之后,安装Xamarin.Forms.Extended.Infinitescrolling NuGet包。右键点击解决方案并选择管理解决方案的NuGet程序包,注:需要选中包括预发行版选项

第五步

现在,在项目XFInfiniteScroll 选中Models文件夹,右击添加一个类,名称为:InfiniteItems,代码如下:

namespace XFInfiniteScroll.Models
{
public class InfiniteItems
{
public string Id { get; set; }
public string Text { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
}

第六步

继续在项目XFInfiniteScroll中,添加一个文件夹,名称为:FakeDataSource,在文件夹中添加一个相当于提供模拟数据的类,名称为:InfiniteDataItems,代码如下:

namespace XFInfiniteScroll.FakeDataSource
{
public static class InfiniteDataItems
{
public static List<InfiniteItems> GetItems()
{
var _items = new List<InfiniteItems>();
_items.Add(new InfiniteItems { Id = "1", Text = "Item1", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "2", Text = "Item2", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "3", Text = "Item3", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "4", Text = "Item4", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "5", Text = "Item5", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "6", Text = "Item6", Title = "FirstItemGronew InfiniteItemsup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "7", Text = "Item7", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "8", Text = "Item8", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "9", Text = "Item9", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "10", Text = "Item10", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "11", Text = "Item11", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "12", Text = "Item12", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "13", Text = "Item13", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "14", Text = "Item14", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "15", Text = "Item15", Title = "FirstItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "16", Text = "Item16", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "17", Text = "Item17", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "18", Text = "Item18", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "19", Text = "Item19", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "20", Text = "Item20", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "21", Text = "Item21", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "22", Text = "Item22", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "23", Text = "Item23", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "24", Text = "Item24", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "25", Text = "Item25", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "26", Text = "Item26", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "27", Text = "Item27", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "28", Text = "Item28", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "29", Text = "Item29", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "30", Text = "Item30", Title = "SecondItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "31", Text = "Item31", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "32", Text = "Item32", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "33", Text = "Item33", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "34", Text = "Item34", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "35", Text = "Item35", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "36", Text = "Item36", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "37", Text = "Item37", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "38", Text = "Item38", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "39", Text = "Item39", Title = "ThirdItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "40", Text = "Item40", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "41", Text = "Item41", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "42", Text = "Item42", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "43", Text = "Item43", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "45", Text = "Item44", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "46", Text = "Item45", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "47", Text = "Item46", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "48", Text = "Item47", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "49", Text = "Item48", Title = "FourthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "50", Text = "Item50", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "51", Text = "Item51", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "52", Text = "Item52", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "53", Text = "Item53", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "54", Text = "Item54", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "55", Text = "Item55", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "56", Text = "Item56", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "57", Text = "Item57", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "58", Text = "Item58", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "59", Text = "Item59", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "60", Text = "Item60", Title = "FifthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "61", Text = "Item61", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "62", Text = "Item62", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "63", Text = "Item63", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "64", Text = "Item64", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "65", Text = "Item65", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "66", Text = "Item66", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "67", Text = "Item67", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "68", Text = "Item68", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "69", Text = "Item69", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "70", Text = "Item70", Title = "SixthItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "71", Text = "Item71", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "72", Text = "Item72", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "73", Text = "Item73", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "74", Text = "Item74", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "75", Text = "Item75", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "76", Text = "Item76", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "77", Text = "Item77", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "78", Text = "Item78", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "79", Text = "Item79", Title = "SeventhItemGroup", Description = "Test Items" });
_items.Add(new InfiniteItems { Id = "80", Text = "Item80", Title = "SeventhItemGroup", Description = "Test Items" }); return _items;
} public static async Task<List<InfiniteItems>> GetItemsAsync(int pageIndex, int pageSize)
{
await Task.Delay(2000);
var _items = GetItems();
return _items.Skip(pageIndex * pageSize).Take(pageSize).ToList();
}
}
}

第七步

由于本项目采用的是选项卡模板,并且目前已使用Shell方式(可以参考:Xamarin.Forms Shell

修改AppShell.xaml文件代码如下:

    <TabBar>
<Tab Title="Infinite Scroll" Icon="icon_about.png">
<ShellContent Title="Single">
<local:SingleViewPage>
</local:SingleViewPage>
</ShellContent>
<ShellContent Title="Group">
<local:GroupViewPage>
</local:GroupViewPage>
</ShellContent>
</Tab>
<ShellContent
Title="About"
ContentTemplate="{DataTemplate local:AboutPage}"
Icon="icon_about.png"
Route="AboutPage" />
<ShellContent
Title="Browse"
ContentTemplate="{DataTemplate local:ItemsPage}"
Icon="icon_feed.png" /> </TabBar>

此处,对于TabbedPage的用法出现错误,因此只能采用此种方法处理页面的布局

在文件夹Views中分别添加SingleViewPageGroupViewPage内容页。直接在下面图片中修改文件名即可。

SingleViewPage页面布局

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="XFInfiniteScroll.Views.SingleViewPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:extended="clr-namespace:Xamarin.Forms.Extended;assembly=Xamarin.Forms.Extended.InfiniteScrolling"
BackgroundColor="Red">
<ContentPage.Content>
<ListView
x:Name="ListSingleItems"
HasUnevenRows="True"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<ListView.Behaviors>
<extended:InfiniteScrollBehavior IsLoadingMore="{Binding IsWorking}">
</extended:InfiniteScrollBehavior>
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="12">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="{Binding Text}">
</Label>
<Label Grid.Row="1" Text="{Binding Description}">
</Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Footer>
<Grid Padding="6">
<Label
HorizontalOptions="Center"
IsVisible="{Binding IsWorking}"
Text="Loading..."
VerticalOptions="Center">
</Label>
</Grid>
</ListView.Footer>
</ListView>
</ContentPage.Content>
</ContentPage>

GroupViewPage页面布局

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="XFInfiniteScroll.Views.GroupViewPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:extended="clr-namespace:Xamarin.Forms.Extended;assembly=Xamarin.Forms.Extended.InfiniteScrolling">
<ContentPage.Content>
<ListView
x:Name="GroupItems"
HasUnevenRows="True"
HorizontalOptions="FillAndExpand"
IsGroupingEnabled="True"
VerticalOptions="FillAndExpand">
<ListView.Behaviors>
<extended:InfiniteScrollBehavior IsLoadingMore="{Binding IsWorking}" />
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*">
</ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20">
</RowDefinition>
<RowDefinition Height="20">
</RowDefinition>
</Grid.RowDefinitions>
<Label
Grid.Row="0"
Text="{Binding Text}"
TextColor="Black">
</Label>
<Label
Grid.Row="1"
Text="{Binding Description}"
TextColor="Black">
</Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell Height="25">
<Grid BackgroundColor="White">
<Label
FontAttributes="None"
FontSize="16"
HorizontalTextAlignment="Center"
Text="{Binding Header}"
TextColor="Blue"
VerticalTextAlignment="Center">
</Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.Footer>
<Grid Padding="6">
<Label
HorizontalOptions="Center"
IsVisible="{Binding IsWorking}"
Text="Load..."
TextColor="Black"
VerticalOptions="Center">
</Label>
</Grid>
</ListView.Footer>
</ListView>
</ContentPage.Content>
</ContentPage>

对于后台代码,可以在GitHub上面参考。https://github.com/mzy666888/XFInfiniteScroll

第八步

现在,可以运行你的Xamarin.Forms应用程序,并可以看到以下的输出内容。

在本机上运行界面:

视频地址:https://www.zhihu.com/zvideo/1338425998501240832

看一下原文中的动图显示

iOS

Android

原文地址https://xmonkeys360.com/2021/01/04/xamarin-forms-infinite-scroll-listview-lazy-loading/

Xamarin.Forms: 无限滚动的ListView(懒加载方式)的更多相关文章

  1. Android 源码解析:单例模式-通过容器实现单例模式-懒加载方式

    本文分析了 Android 系统服务通过容器实现单例,确保系统服务的全局唯一. 开发过 Android 的用户肯定都用过这句代码,主要作用是把布局文件 XML 加载到系统中,转换为 Android 的 ...

  2. vue路由懒加载方式

    方式一:结合Vue的异步组件和Webpack的代码分析 const Home = resole => {require.ensure(['../components/Home.vue'],() ...

  3. js实现图片(高度不确定)懒加载

    最近一直在弄广告页,由于广告页几乎都是图片拼凑起来的,为了减少服务器压力和带宽,采用图片懒加载方式,但是我们的图片高度又不确定,所以我在网上下载了echo.js自己改了一下. 大体思路是:让首页先加载 ...

  4. Selenium截屏 图片未加载的问题解决--【懒加载】

    需求: 截屏后转PDF. 问题: selenium截屏后,图片未加载 如下图: 原因: 网站使用了懒加载技术:只有在浏览器中纵向滚动条滚动到指定的位置时,页面的元素才会被动态加载. 什么是图片懒加载? ...

  5. 黑马程序员-懒加载 lazy loading

    懒加载:延迟加载,当程序启动时不加载资源,当程序需要这些资源时再去加载.需要的时候再加载的一种方式,能够减少内存的占用,效率高.其本质是重写get方法. 背景:由于ios内存有限,如果我们一次性将所有 ...

  6. Ionic3新特性--页面懒加载1

    Ionic3新的懒加载机制给我带来了如下新特性: 避免在每一个使用到某Page的Module或其他Page中重复的import这个类(需要写一堆路径) 允许我们通过字符串key在任何想使用的地方获取某 ...

  7. Ionic3新特性--页面懒加载2加载其他组件

    在第一节中,我们介绍了页面的懒加载方式,并进行了初步的分析,这里,我们将进一步介绍如何配合页面懒加载进行其他组件Component.Pipe.Directive等的模块化,和加载使用. 首先说明一点, ...

  8. JPA数据懒加载LAZY配合事务@Transactional使用(三)

    上篇博文<JPA数据懒加载LAZY和实时加载EAGER(二)>讲到,如果使用懒加载来调用关联数据,必须要保证主查询session(数据库连接会话)的生命周期没有结束,否则,你是无法抽取到数 ...

  9. lazy-init 懒加载的艺术

    懒加载是一种加载方式,加载单例对象一般有两种方式,一是在启动时就立即创建好,另一种则是在需要用到的时候再去加载即懒加载.懒加载一般会针对单例场景,且一般是针对在加载消耗较大费时,且不一定会用到的场景. ...

随机推荐

  1. python解压可迭代对象赋值给多个变量

    如果一个可迭代对象的元素个数超过了变量的个数,会出现"解压值太多"的异常,python提供*号表达式(码夫破石的理解)来解决. 1,求一组平均值,就以类似学生成绩为例,要求是去掉第 ...

  2. 关于新创公司所需的icp,网文,软著和备案的申请

    刚从一个集团离职来到了创业团队,前期是什么都没有,甚至是公司名字都不知道,哈哈.所以就有了后面的坑踩了一遍又一遍.刚开始是在霍尔果斯注册,结果办icp费了半年的时间,东找西找还没下证.又碰上新疆严查不 ...

  3. 基于LNMP架构搭建wordpress博客之安装架构说明

    架构情况 架构情况:基于LNMP架构搭建wordpress系统 软件包版本说明: 系统要求 :  CentOS-6.9-x86_64-bin-DVD1.iso PHP版本  :  php-7.2.29 ...

  4. Python代码打包成exe可执行程序

    首先,打包成exe可执行程序是针对windows平台来说的. 目前比较主流的打包工具就是pyinstaller. 参考:Using PyInstaller 首先安装pyinstaller: pip i ...

  5. 浅析Python闭包

    1.什么是闭包 在介绍闭包概念前,我们先来看一段简短的代码 def sum_calc(*args): def wrapper(): sum = 0 for n in args: sum += n; r ...

  6. [从源码学设计]蚂蚁金服SOFARegistry之Data节点变更

    [从源码学设计]蚂蚁金服SOFARegistry之Data节点变更 目录 [从源码学设计]蚂蚁金服SOFARegistry之Data节点变更 0x00 摘要 0x02 引子 0x03 业务范畴 3.1 ...

  7. RestTemplate发起http请求中文乱码问题解决方案

    RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); MediaType t ...

  8. tcp上传学习二--文本文件上传

    //暮雪超霸.加油!!!package tcp文本上传; import java.io.BufferedReader; import java.io.FileReader; import java.i ...

  9. ethernet

    OSI参考模型 简化相关网络操作:提供不同厂商之间的互联 应用层 为应用程序提供服务 HTTP Telnet 表示层 数据格式化,加密.解密 ASCII EBCDIC JPEG 会话层 建立.维护.管 ...

  10. Github美化 添加徽章

    Github美化 添加徽章 0. 前言 1. 准备 2. 开始 a. 打开shields.io b.制作静态徽章 c.制作动态徽章 d. 结果 3.额外 0. 前言 之前看见很多大项目都有很多勋章,比 ...