
【免费下载链接】NativeScript⚡ Write Native with TypeScript ✨ Best of all worlds (TypeScript, Swift, Objective C, Kotlin, Java, Dart). Use what you love ❤️ Angular, React, Solid, Svelte, Vue with: iOS (UIKit, SwiftUI), Android (View, Jetpack Compose), Flutter and you name it compatible.项目地址https://gitcode.com/gh_mirrors/na/NativeScript点击查看免费下载ListView 是 NativeScript 框架中用于展示垂直滚动列表的核心视图组件底层分别由 Android 的android.widget.ListView与 iOS 的UITableView驱动。本文以packages/core/ui/list-view/Readme.md为骨架结合仓库中的公共实现list-view-common.ts、双平台实现index.android.ts、index.ios.ts以及官方示例页系统讲解 ListView 的数据绑定、事件体系、模板机制、滚动控制与高阶特性分区、吸顶、搜索帮助你从能用进阶到会用、用对。一、快速上手从 Readme 中的最小示例说起packages/core/ui/list-view/Readme.md给出了一个最精简的程序化code-behind创建 ListView 的示例先构造 1000 个数据项再通过itemLoading事件按需创建并复用行视图。这个示例背后其实浓缩了 ListView 三条核心机制数据源可以是普通数组lv.items data直接赋值即可无需任何包装itemLoading事件驱动行视图创建事件参数中的view属性可能已被预填充一个旧视图实例用于复用因此示例中先判断if (!label)再新建Label行视图复用view recyclingListViewBase.prototype.recycleNativeView auto见 list-view-common.ts声明了行视图默认启用自动复用这正是滑动长列表不卡顿的关键。Readme 中的原始示例var lm require(ui/label); var lvm require(ui/list-view); var data []; for(var i 0, l 1000; i l; i) { data.push(i); } var lv new lvm.ListView(); lv.items data; lv.on(lvm.ListView.itemLoadingEvent, function(args){ var label args.view; if(!label) { label new lm.Label(); args.view label; } label.text Item args.index; });该示例完整对应着apps/automated/src/ui/list-view/list-view.md中 Using ListView with Array 一节itemLoading事件负责为每一个即将显示的行创建 UI。注意普通数组在 ListView 显示之后再做增删改不会自动刷新界面此时需要显式调用refresh()方法强制重载。lv.refresh(); // 强制 ListView 重新加载所有 items而如果改用ObservableArray则完全不需要手动刷新——ObservableArray的change事件会被 ListView 自动监听增删数据后界面即时更新。这一机制的底层实现在itemsProperty中list-view-common.ts当items被设为Observable实例时框架会注册ObservableArray.changeEvent的弱事件监听并在数据变化时回调_onItemsChanged→refresh()。二、ListView 的核心事件体系ListView 在 list-view-common.ts 中定义了四个静态事件名同时在 index.d.ts 中给出了完整的事件签名事件常量触发时机事件数据itemLoadingListView.itemLoadingEvent某行即将显示、需要创建视图时ItemEventDataitemTapListView.itemTapEvent列表中的某一项被点击时ItemEventDataloadMoreItemsListView.loadMoreItemsEvent滚动到最后一个可见项时EventDatasearchChangeListView.searchChangeEvent搜索框文本变化时SearchEventDataItemEventDataindex.d.ts包含index行号、view与该项关联的视图、section分区模式下所在分区索引以及平台原生对象iosUITableViewCell与androidViewGroup。SearchEventData则携带text当前搜索文本以及对应的原生搜索组件引用。在 XML 中绑定事件处理函数最为直接Page ListView items{{ myItems }} itemTaplistViewItemTap / /Page// code-behind function listViewItemTap(args) { console.log(Item tapped at index: args.index); }loadMoreItems 是列表分页加载的入口当用户滚动到列表末尾、最后一个 item 可见时触发适合在此追加下一页数据。这一事件在 Android 端由滚动监听器驱动在 iOS 端则由UITableViewDataSource的末尾行判定驱动两端行为保持一致。三、itemTemplate定义行视图最常用的声明方式是直接在 XML 中定义itemTemplate行视图的绑定上下文bindingContext会被自动设置为对应的数据项Page ListView items{{ myItems }} ListView.itemTemplate Label text{{ title || Downloading... }} textWraptrue classtitle / /ListView.itemTemplate /ListView /Page在ListViewBase中itemTemplate可以是XML 字符串或Template 函数list-view-common.ts。当未显式提供模板时会有一个兜底行为_getDefaultItemContent创建一个绑定$value的Labellist-view-common.ts这就是为什么示例中只用items也能看到默认文本行的原因。当itemTemplate属性变化时itemTemplateProperty会自动触发refresh()list-view-common.ts。在__UI_USE_EXTERNAL_RENDERER__外部渲染器如 Vue/React 场景下模板走函数调用路径否则走Builder.parse的 XML 解析路径。程序化写法同样支持模板字符串lv.itemTemplate Label text{{ $value }} /;四、itemTemplates 与 itemTemplateSelector多模板动态选择当列表中存在多种行样式时可以注册多个模板itemTemplates并通过itemTemplateSelector为每一行挑选模板 key。4.1 在 XML 中直接写选择表达式itemTemplateSelector支持在 XML 中直接书写表达式表达式的上下文是当前行的数据项Page ListView items{{ myItems }} itemTemplateSelectorage 18 ? green : red ListView.itemTemplates template keygreen Label text{{ age }} style.backgroundColorgreen / /template template keyred Label text{{ age }} style.backgroundColorred / /template /ListView.itemTemplates /ListView /Page表达式还可以使用特殊变量$index当前行号实现隔行变色ListView items{{ myItems }} itemTemplateSelector$index % 2 0 ? even : odd ListView.itemTemplates template keyeven Label text{{ age }} style.backgroundColorwhite / /template template keyodd Label text{{ age }} style.backgroundColorgray / /template /ListView.itemTemplates /ListView在apps/ui/src/list-view/dynamic-templates-page.xml中可以找到更复杂的表达式组合示例如itemTemplateSelectorage % 2 0 ? green:red其对应的 dynamic-templates-page.ts 还演示了在itemTap中通过listArray.setItem(index, currentItem)更新数据项后即时刷新视图的写法。4.2 用函数实现复杂选择逻辑当选择逻辑无法用单行表达式表达时可将itemTemplateSelector指定为 code-behind 中的函数。该函数接收三个参数dataItem数据项、index行号、items整个数据集合返回值是模板 keyPage ListView items{{ myItems }} itemTemplateSelectorselectItemTemplate ListView.itemTemplates template keygreen Label text{{ age }} style.backgroundColorgreen / /template template keyred Label text{{ age }} style.backgroundColorred / /template /ListView.itemTemplates /ListView /Pagefunction selectItemTemplate(item, index, items) { return item.age 18 ? green : red; }apps/ui/src/list-view/list-view-page.xml中同样给出了函数式选择的完整演练itemTemplateSelectorselectItemTemplate配合red/green/yellow三套模板并演示了表达式选择与函数选择两种写法在同一个页面上并存。4.3 底层实现原理itemTemplateSelector的 setter 做了两种分发list-view-common.ts传字符串时内部创建一个Label作为绑定代理_itemTemplateSelectorBindable将表达式绑定到其templateKey属性每次求值时把当前数据项设为bindingContext并取出结果传函数时直接保存函数引用。实际取模板的入口是_getItemTemplate(index)list-view-common.ts先调用 selector 得到templateKey再在_itemTemplatesInternal中按 key 查找找不到匹配 key 时回退到索引为 0 的默认模板_defaultTemplate。itemTemplates字符串值会经由Builder.parseMultipleTemplates解析为KeyedTemplate[]list-view-common.ts。五、常用属性与样式配置5.1 itemsitems可以是普通数组也可以是实现了ItemsSource接口lengthgetItem(index)见 index.d.ts的任意对象。赋值时会自动为ObservableArray挂上change监听list-view-common.ts实现增量更新。5.2 rowHeight控制行高默认值为auto支持长度类型如50、50dp、50%。该属性由rowHeightProperty管理list-view-common.ts内部会转换为设备像素并存入_effectiveRowHeight当原生视图尚未就绪时会被强制回退为auto。仓库的apps/ui/src/list-view/row-height-page.xml提供了行高场景的实测页面。5.3 separatorColor分隔线颜色同时可通过 CSS 属性separator-color设置。底层是注册在Style上的CssPropertylist-view-common.tsListView separatorColor#e0e0e0 items{{ myItems }} /ListView { separator-color: #e0e0e0; }5.4 iosEstimatedRowHeight仅 iOS设置 iOS 端的行高估算值默认44px。估算值影响UITableView的初始滚动条长度与首屏布局实际行高仍以rowHeight为准。对应属性见 list-view-common.ts 与 index.ios.ts。5.5 itemIdGenerator自定义 item 的唯一 ID 生成函数签名(item, index, items) number默认以index作为 IDlist-view-common.ts。在行视图复用与原生差异计算中起到关键作用。六、滚动控制与可见性判断ListView 提供三类滚动 APIindex.d.ts方法行为refresh()强制重新加载全部 itemscrollToIndex(index)将指定 index 的行滚动到可视区域Android 对应setSelectioniOS 对应scrollToRowAtIndexPathscrollToIndexAnimated(index)带动画滚动到指定行Android 对应smoothScrollToPositionisItemAtIndexVisible(index)判断指定 index 的行当前是否可见lv.scrollToIndex(50); // 直接跳转 lv.scrollToIndexAnimated(50); // 平滑滚动 if (lv.isItemAtIndexVisible(50)) { console.log(第 50 行可见); }apps/ui/src/list-view/list-view-page.ts中的示例页面提供了 RESET、SCROLL、SCROLL TO INDEX 50、SCROLL TO INDEX 50 ANIMATED 四个按钮可直接体验两种滚动方式与 reset 的差异。需要注意的是ListViewBase中的scrollToIndex等只是空壳占位list-view-common.ts真正实现位于各平台文件中这也是公共基类定义契约、平台文件实现原生细节的典型分层。七、高阶特性分区列表sectioned与吸顶头sticky headerListView支持分区数据 吸顶头sectioned默认false开启后items数组中的每个元素应是一个包含items属性该分区内容的对象每个分区拥有自己的吸顶头stickyHeader默认false开启后滚动经过分区时头部保持吸顶stickyHeaderTemplate吸顶头的模板stickyHeaderHeight吸顶头高度默认autostickyHeaderTopPadding是否保留 iOS 分区头之上的默认间距约 4-5px默认false以获得更紧凑的布局。这些属性在 list-view-common.ts 中注册对应的分区数据访问逻辑有_getSectionCount、_getItemsInSection、_getDataItemInSectionlist-view-common.ts并且ItemEventData.section字段会携带分区号。ListView sectionedtrue stickyHeadertrue items{{ sections }} ListView.stickyHeaderTemplate Label text{{ title }} backgroundColor#dddddd / /ListView.stickyHeaderTemplate ListView.itemTemplate Label text{{ name }} / /ListView.itemTemplate /ListViewAndroid 端吸顶头通过原生滚动监听器跟踪滚动位置并动态调整 header 层级实现代码中定义了STICKY_HEADER_Z_INDEX 1000并维护_hiddenHeaderPositions集合index.android.tsiOS 端则使用UITableViewHeaderFooterViewListViewHeaderCell承载吸顶头index.ios.ts。八、内置搜索showSearch 与 searchChangeListView 还集成了列表内搜索能力showSearch默认false开启后iOS 使用原生UISearchControllerAndroid 使用原生SearchViewsearchAutoHide默认false仅 iOS滚动时搜索栏自动隐藏、上滑时重新出现iosSearchInsetBehavior仅 iOS控制开启showSearch时底层UIScrollView的contentInsetAdjustmentBehavior可选automatic | scrollableAxes | never | always。默认在UINavigationController场景下为automatic为导航栏/大标题预留空间当搜索栏作为tableHeaderView时则为neverlist-view-common.ts。搜索文本变化通过searchChange事件上报事件数据SearchEventData携带text、iosUISearchController与android原生搜索视图字段index.d.tsListView showSearchtrue searchChangeonSearchChanged items{{ myItems }} /function onSearchChanged(args) { console.log(Search text: args.text); // 在此基于 args.text 过滤数据源并赋值给 items }Android 端搜索视图与监听器SearchView.OnQueryTextListener的创建逻辑位于 index.android.ts并定义了SEARCH_VIEW_Z_INDEX 2000保证搜索栏悬浮于列表之上。九、代码组织与延伸阅读ListView 的模块结构体现了 NativeScript 组件公共基类 双平台实现的标准布局packages/core/ui/list-viewlist-view-common.ts跨平台公共逻辑、属性注册与事件定义index.android.tsAndroid 实现基于android.widget.ListView、AdapterView.OnItemClickListener包含行视图回收池_availableViews/_realizedItems与吸顶、搜索实现index.ios.tsiOS 实现基于UITableView、UITableViewDataSource、UITableViewDelegate包含ListViewCell/ListViewHeaderCell原生 Cell 类index.d.ts完整类型声明与事件签名。进一步的实战示例可以查阅apps/ui/src/list-view/list-view-page.xml多模板 表达式/函数 selector 滚动控制的一体化演示页apps/ui/src/list-view/dynamic-templates-page.xml按数据动态换模板 itemTap 更新数据的完整闭环apps/ui/src/list-view/row-height-page.xml行高定制场景apps/automated/src/ui/list-view/list-view-tests.ts自动化测试用例可作为行为验证的参考。要点回顾普通数组 itemLoading事件是 ListView 最朴素的使用方式注意数组变更需手动refresh()生产环境优先使用ObservableArray或ItemsSource以获得自动增量更新多模板通过itemTemplatesitemTemplateSelector表达式或函数实现未知 key 会自动回退到默认模板分页加载、分区吸顶、内置搜索等进阶能力均有一一对应的属性与事件。掌握这些机制你就能在 NativeScript 中构建出高性能、可维护的长列表界面。赞分享【免费下载链接】NativeScript⚡ Write Native with TypeScript ✨ Best of all worlds (TypeScript, Swift, Objective C, Kotlin, Java, Dart). Use what you love ❤️ Angular, React, Solid, Svelte, Vue with: iOS (UIKit, SwiftUI), Android (View, Jetpack Compose), Flutter and you name it compatible.项目地址https://gitcode.com/gh_mirrors/na/NativeScript点击查看免费下载相关推荐NativeScript WebView 完整实战指南从 XML 声明到加载远程 URL、本地文件与原始 HTMLNativeScript WebView 完整实战指南从 XML 声明到加载远程 URL、本地文件与原始 HTML WebView 是 NativeScripmbart-large-50-many-to-many-mmt50种语言互译的终极AI翻译模型揭秘 mbart large 50 many to many mmt50种语言互译的终极AI翻译模型揭秘 想要实现50种语言之间的无缝互译吗 mbart l终极指南3分钟掌握国家中小学智慧教育平台电子课本下载技巧终极指南3分钟掌握国家中小学智慧教育平台电子课本下载技巧 还在为无法下载国家中小学智慧教育平台的电子教材而烦恼吗今天我要向你推荐一个超实用的开源工具——tc网页爬虫教育上一篇Home Assistant 智能门锁集成教程远程解锁、一次性密码与门状态提醒完整指南下一篇Fathom Lite HTTP客户端实现client.js源码解读创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考