说明

在本博客中,学习如何在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. java基础:方法的定义和调用详细介绍,方法同时获取数组最大值和最小值,比较两个数组,数组交换最大最小值,附练习案列

    1. 方法概述 1.1 方法的概念 方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建才可以使用,该过程成为方法定义 方法创建后并不是直接可 ...

  2. Astra示例程序库正式上线啦

    新上线的Astra示例程序库提供了基于多种编程语言和框架使用Astra的例子.借助这个示例程序库,你可以在短时间内建构起数据库.创建多个表.装载示例数据并部署基于Cassandra的应用程序. 什么是 ...

  3. struts文件上传拦截器分析

    struts有默认的文件拦截器,一般配置maximumSize就可以了. 知道原理,我们可以写一个类继承它,实现自己的配置上传文件大小的方式.   然后细究页面上传文件的时候,发现了一些问题. act ...

  4. [leetcode]692. Top K Frequent Words频率最高的前K个单词

    这个题的排序是用的PriorityQueue实现自动排列,优先队列用的是堆排序,堆排序请看:http://www.cnblogs.com/stAr-1/p/7569706.html 自定义了优先队列的 ...

  5. TurtleBot3 Waffle (tx2版华夫)(12)建图-hector建图

    1)[Remote PC] 启动roscore $ roscore 2)[TurBot3] 启动turbot3 $ roslaunch turbot3_bringup minimal.launch 3 ...

  6. Java 初中级程序员如何快速成长???

    Java 技术学习路线 Java 语言是一门非常流行和重要的语言,目前仍是需求量很大的语言,应用范围很广的语言,在企业级开发.移动开发.大数据云计算.人工智能等领域都有大量的应用. 怎么样学习好 Ja ...

  7. 论文阅读 Characterization of Multiple 3D LiDARs for Localization and Mapping using Normal Distributions Transform

    Abstract 在这个文章里, 我们细致的比较了10种不同的3D LiDAR传感器, 用了一般的 Normal Distributions Transform (NDT) 算法. 我们按以下几个任务 ...

  8. SQL Server批量向表中插入多行数据语句

    因自己学习测试需要,需要两个有大量不重复行的表,表中行数越多越好.手动编写SQL语句,通过循环,批量向表中插入数据,考虑到避免一致问题,设置奇偶行不同.个人水平有限,如有错误,还望指正. 语句如下: ...

  9. spring boot 邮件服务

    引入依赖 添加spring-boot-starter-mail包引用 <dependency> <groupId>org.springframework.boot</gr ...

  10. python中环境变量的使用

    前言 之前就经常用,今天来凑个篇数. 在开发的过程中,我们经常会将代码中某些可能更改的,比如redis地址,数据库地址,限流阈值等参数写活来提高灵活性, 传统的方式可能是写在配置文件中,比如 xml ...