Skip to content

列表 ListView

qt-list-view 是同 ul 一样注册的用于多功能的列表组件,增加数据代理,常用于单行多列的内容排版。支持横向纵向排列滚动,支持数据分页。

  • 特点,初始化组件返回数据代理值,直接操作返回值更新ui视图,减少冗余api,降低开发成本。

  • 注意,最低支持SDK版本2.1

  • 注意,当前文档demo中默认item样式使用[qt-poster],在构建数据中可查看其使用方式。也可自定义item。

  • 注意,自定义item样式中文本标签仅支持[text-view]。

基础用法

点击查看源码
vue
<script lang="ts">
import {defineComponent, ref} from 'vue';
import {QTIListView, QTListViewItem, QTPoster} from '@quicktvui/quicktvui3';

export default defineComponent({
	setup() {
		const listViewRef = ref<QTIListView>();
		let arr: Array<QTListViewItem> = [];
		let listDataRec: Array<QTListViewItem> = [];
		for (let i = 0; i < 24; i++) {
			let imgSrc =
				'https://img1.baidu.com/it/u=2666955302,2339578501&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750';
			const poster: QTPoster = {
				type: 10001,
				decoration: {top: 20, left: 20, right: 20, bottom: 20},
				title: {
					text: '主标题' + i,
					enable: true,
					style: {width: 260},
				},
				style: {width: 260, height: 320},
				titleStyle: {width: 260, height: 120, marginTop: 320 - 60},
				titleFocusStyle: {width: 260, marginTop: 320 - 100},
			};
			arr.push(poster);
		}

		listDataRec = listViewRef.value!.init(arr);

		// 	初始化组件之后返回值常用操作

		//  获取引用类型值 let getData = JSON.parse(JSON.stringify(listDataRec))

		//  获取基本类型值 listDataRec[0].assetTitle

		//  修改值 listDataRec[0].assetTitle = '更新assetTitle'

		//  push   listDataRec.push({ 单条数据 }) | listDataRec.push(...[多条数据]) //push方法

		//  pop    listDataRec.pop() //pop方法 末尾删除一条item

		//  concat listDataRec.concat(data) //concat方法 链接listDataRec数据

		// 	splice(1个参数) 删除 listDataRec.splice(1)    //splice方法删除 从第一项开始删除之后所有item

		// 	splice(2个参数) 删除 listDataRec.splice(1, 2) //splice方法删除 (从第1个开始 删除2条item)

		// 	splice(3个参数 - 替换) listDataRec.splice(4, 2, data)    //splice方法-替换 从索引位置 4 开始,替换两个元素,替换的data (当三个参数第二个参数不为0时 为替换)

		// 	splice(3个参数 - 插入) listDataRec.splice(4, 0, data)    //splice方法-插入 从索引位置 4 开始,替换0,插入的data (当三个参数第二个参数为0时 为插入)仅支持runtime版本 2.3+

		//   forEach循环   listDataRec.forEach(el => { el.assetTitle = '修改assetTitle' }) //循环修改每个item的值 整体更新

		//   for循环   for (let i = 0; i < listDataRec.length; i++) { if () { } } //循环更新符合条件的每个item 当筛选个别条件的item时可以使用for循环,当循环修改每个item的值时建议使用forEach循环

		//   重新赋值   listDataRec.splice(0); listDataRec.push(...data)  // 整体更新

		return {
			listViewRef,
		};
	},
});
</script>

<template>
	<qt-list-view
		class="list_view"
		ref="listViewRef"
	>
		<!-- 结合poster组件快速生成item 亦可自定义item-->
		<qt-poster />
	</qt-list-view>
</template>

注意事项

  • qt-list-view HTML片段中type属性值要与data中的type值对应。

  • qt-list-view HTML片段中设置属性值需要使用 ${属性值}

  • qt-list-view HTML片段中文本标签仅支持 <text-view>

分页效果

点击查看源码
vue
<script lang="ts">
import {defineComponent, ref, nextTick} from 'vue';
import {QTIListView, QTListViewItem, QTPoster} from '@quicktvui/quicktvui3';

export default defineComponent({
	setup() {
		const listViewRef = ref<QTIListView>();
		let listDataRec: Array<QTListViewItem> = [];
		const loadMore = (pageNo: number) => {
			let arr: Array<QTListViewItem> = [];
			for (let i = pageNo * 6 - 6; i < pageNo * 6; i++) {
				const poster: QTPoster = {
					type: 10001,
					decoration: {top: 20, left: 20, right: 20, bottom: 20},
					title: {
						text: '主标题' + i,
						enable: true,
						style: {width: 260},
					},
					style: {width: 260, height: 320},
					titleStyle: {width: 260, height: 120, marginTop: 320 - 60},
					titleFocusStyle: {width: 260, marginTop: 320 - 100},
				};
			}
			if (listDataRec.length > 0) {
				if (pageNo > 4) {
					//如果分页请求完毕 调用 stopPage 方法
					listViewRef.value?.stopPage();
				} else {
					listDataRec.push(...arr);
				}
			} else {
				nextTick(() => {
					listDataRec = listViewRef.value!.init(arr);
				});
			}
		};

		const onItemBind = () => void 0;

		return {
			onItemBind,
			loadMore,
		};
	},
});
</script>

<template>
	<qt-list-view
		class="list_view"
		ref="listViewRef"
		@item-bind="onItemBind"
		horizontal
		:listenBoundEvent="true"
		:loadMore="loadMore"
		:openPage="true"
	>
		<qt-poster />
		<!-- loading样式  -->
		<qt-view
			class="loading"
			type="1002"
			name="loading"
			ref="loading"
			:focusable="false"
		>
			<qt-loading-view
				color="#409eff"
				style="height: 30px; width: 30px"
			/>
		</qt-view>
	</qt-list-view>

	<qt-list-view
		class="list_view"
		ref="listViewRef"
		@item-bind="onItemBind"
		horizontal
		:listenBoundEvent="true"
		:loadMore="loadMore"
		:openPage="true"
	>
		<qt-poster />
		<!-- loading样式  -->
		<qt-view
			class="loading"
			type="1002"
			name="loading"
			ref="loading"
			:focusable="false"
		>
			<qt-loading-view
				color="#409eff"
				style="height: 30px; width: 30px"
			/>
		</qt-view>
	</qt-list-view>
</template>

注意事项

  • listenBoundEvent 属性必须设置为true @item-bind 方法必须添加 可以不做任何处理 openPage 属性值为true

  • qt-list-view 嵌套时,分页仅支持最外层

  • loading type 必须设置为1002

  • stopPage() 分页结束后调用该方法停止分页

  • 分页结束后重新开启分页可v-if刷新组件

设置滑动方向

点击查看源码
vue
<script lang="ts">
// ...
</script>

<template>
	<!-- 注意:不可动态改变此属性,竖向滑动时不需要配置此属性) -->

	<!-- 横向滑动 -->
	<qt-list-view horizontal> ... </qt-list-view>

	<!-- 纵向滑动 -->
	<qt-list-view> ... </qt-list-view>
</template>

注意事项

  • horizontal属性:切换列表为横向滑动(注意:不可动态改变此属性,纵向滑动时不需要配置此属性)

注意事项

  • list-view中每个item样式的margin无效,需要数据中decorate的值来设置外边距

属性

参数描述类型默认值
*:initPositionfocusPosition:请求焦点的位置,可以不传,不传不会请求焦点;scrollToPosition:首次滚动的位置,可以不传;scrollOffset:首次滚动的偏移量,可以不传。Map
*horizontal切换列表为横向滑动,使用如下。Booleanfalse
*advancedFocusSearchSpan寻焦搜索范围,使用如下。int
:padding设置内边距 顺序:'left,top,right,bottom'String
clipChildren设置是否将超出边界的子qt-list-view切除boolean
:listenBoundEvent是否开启绑定监听回调,开启分页时必须设置该参数为trueBooleanfalse
:disableScrollOnFirstScreen是否开启列表在展示第一屏数据时切换焦点不滑动Booleanfalse
:checkScrollOffsetOnStateChanged是否开启滑动事件onScrollStateChanged监听回调Booleanfalse
:scrollEventThrottle滑动事件onScrolled监听回调间隔时间,配合onScrollEnable属性使用,单位:毫秒Int400
:onScrollEnable是否开启滑动事件onScrolled监听回调Booleanfalse
:scrollYLesserReferenceValue向上滑动偏移量,配合onScrollEnable属性使用Int-1
:scrollYGreaterReferenceValue向下滑动偏移量,配合onScrollEnable属性使用Int-1
:layoutTargetPosition指定某个item更新外部定义方法,详情请见TriggerTaskModuleInt-1
:makeChildVisibleType指定某个子视图显示在屏幕中位置的类型,共分为:center:居中显示;normal:默认显示; none:只显示viewgroup矩形区域String"center"
:makeChildVisibleClampBackward焦点向下,列表上滑到屏幕中最后一个元素时的向上滑动偏移量(只有在:makeChildVisibleType属性不为center时有效)Int0
:makeChildVisibleClampForward焦点向上,列表下滑到屏幕中最后一个元素时的向下滑动偏移量(只有在:makeChildVisibleType属性不为center时有效)Int0
:scrollThresholdHorizontal列表水平滑动时触发item显示在屏幕正中间位置的阀值(超过阀值则触发,只有在:makeChildVisibleType属性为center时有效)Int300
:scrollThresholdVertical列表垂直滑动时触发item显示在屏幕正中间位置的阀值(超过阀值则触发,只有在:makeChildVisibleType属性为center时有效)Int50
:cachePool设置adapter的缓存池;示例cachePool:{ name:"tvList"+Date.now(), size:{ 10000:10, } },Map
:cachePoolName设置当前使用缓存池名称String
:focusMemory是否开启焦点强制移动(寻焦速度更快)Booleantrue
:setSelectChildPosition设置选中的子view,此属性只在view已经显示出来才有效Int0
:shakePreCheckNumber设置列表滑动到底部触发回弹动画时的提前量(横向滑动时是滑动到最右)Int2
:endHintEnabled是否开启列表回弹动画Booleantrue
:listenFocusSearchOnFail是否开启当焦点寻焦失败时的事件回调Booleantrue
:enableSelectOnFocus是否开启指定获取焦点Booleantrue
:useAdvancedFocusSearch是否关闭recyclerView的默认焦点搜索Booleantrue
:enableKeepFocus是否开启焦点预处理Booleanfalse
:initFocusPositionAfterLayout设置焦点初始默认位置Int-1
:blockFocusDirections某个方向锁住焦点Array ['left', 'right', 'up', 'down']
:loadMore开启分页的回调,接收(pageNo)根据页码处理数据 openPage为true时生效Function
:openPage是否开启分页Booleanfalse
*:autoscroll (sdk>=2.8)列表完成重建时,列表将自动滚动到autoscroll指定位置及偏移量Array[position,scrollOffset]null
  • initPosition参数:
参数名类型说明
focusPositionInt焦点默认位置
scrollToPositionInt默认滑动位置
scrollOffsetInt滑动偏移量
  • autoscroll参数:
参数名类型说明
positionInt指定滚动位置
scrollOffsetInt滚动偏移量(通常计算方式为:scrollOffset = (list高度 - item高度) / 2

方法

init(data)

初始化qt-list-view组件,有返回值,操作返回值更新视图

参数名类型说明
dataArray列表数据集合

注意: 获取基本类型数据可以直接操作返回值使用,获取引用类型数据可以通过JSON.parse(JSON.stringify(返回值))获取;

js
  初始化 listDataRec = listViewRef.value!.init(data)

init返回值相关API

function描述
pushlistDataRec.push({单条数据}) listDataRec.push(...[多条数据])
poplistDataRec.pop() 末尾删除一条item
concatlistDataRec.concat() 链接listDataRec数据
splice(1个参数)删除 listDataRec.splice(1) 从第一项开始删除之后所有item
splice(2个参数)删除 listDataRec.splice(1,2) 从第1个开始 删除2条item
splice(3个参数-替换)listDataRec.splice(4, 2, data) 从索引位置 4 开始,替换两个元素,替换的data (当三个参数第二个参数不为0时 为替换)
splice(3个参数-插入)listDataRec.splice(4, 0, data) 从索引位置 4 开始,替换0,插入的data (当三个参数第二个参数为0时 为插入)仅支持runtime版本 2.3+
forEachlistDataRec.forEach(el => {el.assetTitle = '修改assetTitle'}) //循环修改每个item的值 整体更新


scrollToTop()

列表滑动到顶部

js
  listViewRef.value!.scrollToTop()

setDisplay(display)

设置列表是否显示

参数名类型说明
displayBoolean是否显示

js
  listViewRef.value!.setDisplay(false)

scrollToPosition(index)

滑动到指定位置

参数名类型说明
indexInt要滑到的位置

js
  listViewRef.value!.scrollToPosition(index)

scrollToIndex(y, anim, offsetndex)

滑动到指定位置并附带动画和偏移量

参数名类型说明
yInt要滑到的位置
animBoolean是否开启动画
offsetndexInt偏移量

js
  listViewRef.value!.scrollToIndex(y, anim, offsetndex)

setItemFocused(pos)

设置指定子Item获取焦点

参数名类型说明
posInt子Item位置

js
  listViewRef.value!.setItemFocused(pos)

setItemSelected(pos,b)

设置选中的子item,注意此方法只在view已经显示出来以后调用才有效

参数名类型说明
posInt要选中的子View位置
bBoolean设置要选中的子View的焦点

js
  listViewRef.value!.setItemSelected(pos, b)

stopPage()

当在分页加载完数据时,调用该方法停止分页关闭进度条样式

js
  listViewRef.value!.stopPage()

事件

@item-click

Item点击事件回调

参数名类型说明
positionInt点击Item的位置(在子布局里)
parentPositionInt点击Item的在父布局中的位置
nameString点击Item的name类型
itemObject当前点击item绑定的数据

@item-focused

Item焦点事件回调

参数名类型说明
positionInt焦点所在Item的位置(在子布局里)
parentPositionInt焦点所在Item的在父布局中的位置
hasFocusBoolean焦点所在Item是否获得焦点
nameString点击Item的name类型
itemObject当前点击item绑定的数据

@item-bind

Item绑定事件回调

参数名类型说明
positionInt绑定Item的位置
nameString绑定Item的name

@item-unbind

Item解除绑定事件回调

参数名类型说明
positionInt解除绑定Item的位置
nameString解除绑定Item的name

@scroll

列表滑动onScroll事件回调

参数名类型说明
contentOffsetMap滑动参数

contentOffset参数:

参数名类型说明
xFloat列表滑动x轴偏移量
yFloat列表滑动y轴偏移量

@scroll-state-changed

列表滑动onScrollStateChanged事件回调

参数名类型说明
contentOffsetMap滑动参数
stateMap滑动状态

contentOffset参数:

参数名类型说明
xFloat列表滑动x轴偏移量
yFloat列表滑动y轴偏移量

state参数:

参数名类型说明
oldStateInt之前列表滑动状态
newStateInt当前列表滑动状态

@focus-search-failed

列表寻焦失败事件回调

参数名类型说明
childMap当前焦点所在item
focusedMap焦点将要落在item
directionInt滑动方向

child参数:

参数名类型说明
indexInt当前item的位置
idInt当前item的id
nameString当前item的name

focused参数:

参数名类型说明
idInt焦点将要落在item的id
nameString焦点将要落在item的name

常见问题 Q&A

  • horizontaladvancedFocusSearchSpanpadding属性不可动态改变,这三个在list-view初始化时就确定

  • 要实现onItemClickonItemFocus回调,需要在item中加上属性eventClickeventFocus,这样才能让item响应点击和焦点事件

  • :scrollThresholdHorizontal:scrollThresholdVertical属性的生效条件是:makeChildVisibleType='center'