列表 ListView
qt-list-view
是同 ul
一样注册的用于多功能的列表组件,增加数据代理,常用于单行多列的内容排版。支持横向纵向排列滚动,支持数据分页。
特点,初始化组件返回数据代理值,直接操作返回值更新ui视图,减少冗余api,降低开发成本。
注意,最低支持SDK版本
2.1
。注意,当前文档demo中默认item样式使用[
qt-poster
],在构建数据中可查看其使用方式。也可自定义item。注意,自定义item样式中文本标签仅支持[
text-view
]。
基础用法
![](/component/listview/list_view_basic.gif)
点击查看源码
<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>
。
分页效果
![](/component/listview/list_view_page.gif)
点击查看源码
<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刷新组件
设置滑动方向
![](/component/listview/list_view_orientation.gif)
点击查看源码
<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的值来设置外边距
属性
参数 | 描述 | 类型 | 默认值 |
---|---|---|---|
*:initPosition | focusPosition:请求焦点的位置,可以不传,不传不会请求焦点;scrollToPosition:首次滚动的位置,可以不传;scrollOffset:首次滚动的偏移量,可以不传。 | Map | 无 |
*horizontal | 切换列表为横向滑动,使用如下。 | Boolean | false |
*advancedFocusSearchSpan | 寻焦搜索范围,使用如下。 | int | 无 |
:padding | 设置内边距 顺序:'left,top,right,bottom' | String | 无 |
clipChildren | 设置是否将超出边界的子qt-list-view 切除 | boolean | |
:listenBoundEvent | 是否开启绑定监听回调,开启分页时必须设置该参数为true | Boolean | false |
:disableScrollOnFirstScreen | 是否开启列表在展示第一屏数据时切换焦点不滑动 | Boolean | false |
:checkScrollOffsetOnStateChanged | 是否开启滑动事件onScrollStateChanged监听回调 | Boolean | false |
:scrollEventThrottle | 滑动事件onScrolled监听回调间隔时间,配合onScrollEnable属性使用,单位:毫秒 | Int | 400 |
:onScrollEnable | 是否开启滑动事件onScrolled监听回调 | Boolean | false |
:scrollYLesserReferenceValue | 向上滑动偏移量,配合onScrollEnable属性使用 | Int | -1 |
:scrollYGreaterReferenceValue | 向下滑动偏移量,配合onScrollEnable属性使用 | Int | -1 |
:layoutTargetPosition | 指定某个item更新外部定义方法,详情请见TriggerTaskModule | Int | -1 |
:makeChildVisibleType | 指定某个子视图显示在屏幕中位置的类型,共分为:center:居中显示;normal:默认显示; none:只显示viewgroup矩形区域 | String | "center" |
:makeChildVisibleClampBackward | 焦点向下,列表上滑到屏幕中最后一个元素时的向上滑动偏移量(只有在:makeChildVisibleType 属性不为center时有效) | Int | 0 |
:makeChildVisibleClampForward | 焦点向上,列表下滑到屏幕中最后一个元素时的向下滑动偏移量(只有在:makeChildVisibleType 属性不为center时有效) | Int | 0 |
:scrollThresholdHorizontal | 列表水平滑动时触发item显示在屏幕正中间位置的阀值(超过阀值则触发,只有在:makeChildVisibleType 属性为center时有效) | Int | 300 |
:scrollThresholdVertical | 列表垂直滑动时触发item显示在屏幕正中间位置的阀值(超过阀值则触发,只有在:makeChildVisibleType 属性为center时有效) | Int | 50 |
:cachePool | 设置adapter的缓存池;示例cachePool:{ name:"tvList"+Date.now(), size:{ 10000:10, } }, | Map | 无 |
:cachePoolName | 设置当前使用缓存池名称 | String | 无 |
:focusMemory | 是否开启焦点强制移动(寻焦速度更快) | Boolean | true |
:setSelectChildPosition | 设置选中的子view,此属性只在view已经显示出来才有效 | Int | 0 |
:shakePreCheckNumber | 设置列表滑动到底部触发回弹动画时的提前量(横向滑动时是滑动到最右) | Int | 2 |
:endHintEnabled | 是否开启列表回弹动画 | Boolean | true |
:listenFocusSearchOnFail | 是否开启当焦点寻焦失败时的事件回调 | Boolean | true |
:enableSelectOnFocus | 是否开启指定获取焦点 | Boolean | true |
:useAdvancedFocusSearch | 是否关闭recyclerView的默认焦点搜索 | Boolean | true |
:enableKeepFocus | 是否开启焦点预处理 | Boolean | false |
:initFocusPositionAfterLayout | 设置焦点初始默认位置 | Int | -1 |
:blockFocusDirections | 某个方向锁住焦点 | Array ['left', 'right', 'up', 'down'] | 无 |
:loadMore | 开启分页的回调,接收(pageNo)根据页码处理数据 openPage为true时生效 | Function | 无 |
:openPage | 是否开启分页 | Boolean | false |
*:autoscroll (sdk>=2.8) | 列表完成重建时,列表将自动滚动到autoscroll 指定位置及偏移量 | Array[position,scrollOffset] | null |
initPosition
参数:
参数名 | 类型 | 说明 |
---|---|---|
focusPosition | Int | 焦点默认位置 |
scrollToPosition | Int | 默认滑动位置 |
scrollOffset | Int | 滑动偏移量 |
autoscroll
参数:
参数名 | 类型 | 说明 |
---|---|---|
position | Int | 指定滚动位置 |
scrollOffset | Int | 滚动偏移量(通常计算方式为:scrollOffset = (list高度 - item高度) / 2 ) |
方法
init(data)
初始化qt-list-view
组件,有返回值,操作返回值更新视图
参数名 | 类型 | 说明 |
---|---|---|
data | Array | 列表数据集合 |
注意: 获取基本类型数据可以直接操作返回值使用,获取引用类型数据可以通过JSON.parse(JSON.stringify(返回值))获取;
初始化 listDataRec = listViewRef.value!.init(data)
init返回值相关API
function | 描述 |
---|---|
push | listDataRec.push({单条数据}) listDataRec.push(...[多条数据]) |
pop | listDataRec.pop() 末尾删除一条item |
concat | listDataRec.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+ |
forEach | listDataRec.forEach(el => {el.assetTitle = '修改assetTitle'}) //循环修改每个item的值 整体更新 |
scrollToTop()
列表滑动到顶部
listViewRef.value!.scrollToTop()
setDisplay(display)
设置列表是否显示
参数名 | 类型 | 说明 |
---|---|---|
display | Boolean | 是否显示 |
listViewRef.value!.setDisplay(false)
scrollToPosition(index)
滑动到指定位置
参数名 | 类型 | 说明 |
---|---|---|
index | Int | 要滑到的位置 |
listViewRef.value!.scrollToPosition(index)
scrollToIndex(y, anim, offsetndex)
滑动到指定位置并附带动画和偏移量
参数名 | 类型 | 说明 |
---|---|---|
y | Int | 要滑到的位置 |
anim | Boolean | 是否开启动画 |
offsetndex | Int | 偏移量 |
listViewRef.value!.scrollToIndex(y, anim, offsetndex)
setItemFocused(pos)
设置指定子Item获取焦点
参数名 | 类型 | 说明 |
---|---|---|
pos | Int | 子Item位置 |
listViewRef.value!.setItemFocused(pos)
setItemSelected(pos,b)
设置选中的子item,注意此方法只在view已经显示出来以后调用才有效
参数名 | 类型 | 说明 |
---|---|---|
pos | Int | 要选中的子View位置 |
b | Boolean | 设置要选中的子View的焦点 |
listViewRef.value!.setItemSelected(pos, b)
stopPage()
当在分页加载完数据时,调用该方法停止分页关闭进度条样式
listViewRef.value!.stopPage()
事件
@item-click
Item点击事件回调
参数名 | 类型 | 说明 |
---|---|---|
position | Int | 点击Item的位置(在子布局里) |
parentPosition | Int | 点击Item的在父布局中的位置 |
name | String | 点击Item的name类型 |
item | Object | 当前点击item绑定的数据 |
@item-focused
Item焦点事件回调
参数名 | 类型 | 说明 |
---|---|---|
position | Int | 焦点所在Item的位置(在子布局里) |
parentPosition | Int | 焦点所在Item的在父布局中的位置 |
hasFocus | Boolean | 焦点所在Item是否获得焦点 |
name | String | 点击Item的name类型 |
item | Object | 当前点击item绑定的数据 |
@item-bind
Item绑定事件回调
参数名 | 类型 | 说明 |
---|---|---|
position | Int | 绑定Item的位置 |
name | String | 绑定Item的name |
@item-unbind
Item解除绑定事件回调
参数名 | 类型 | 说明 |
---|---|---|
position | Int | 解除绑定Item的位置 |
name | String | 解除绑定Item的name |
@scroll
列表滑动onScroll事件回调
参数名 | 类型 | 说明 |
---|---|---|
contentOffset | Map | 滑动参数 |
contentOffset参数:
参数名 | 类型 | 说明 |
---|---|---|
x | Float | 列表滑动x轴偏移量 |
y | Float | 列表滑动y轴偏移量 |
@scroll-state-changed
列表滑动onScrollStateChanged事件回调
参数名 | 类型 | 说明 |
---|---|---|
contentOffset | Map | 滑动参数 |
state | Map | 滑动状态 |
contentOffset参数:
参数名 | 类型 | 说明 |
---|---|---|
x | Float | 列表滑动x轴偏移量 |
y | Float | 列表滑动y轴偏移量 |
state参数:
参数名 | 类型 | 说明 |
---|---|---|
oldState | Int | 之前列表滑动状态 |
newState | Int | 当前列表滑动状态 |
@focus-search-failed
列表寻焦失败事件回调
参数名 | 类型 | 说明 |
---|---|---|
child | Map | 当前焦点所在item |
focused | Map | 焦点将要落在item |
direction | Int | 滑动方向 |
child参数:
参数名 | 类型 | 说明 |
---|---|---|
index | Int | 当前item的位置 |
id | Int | 当前item的id |
name | String | 当前item的name |
focused参数:
参数名 | 类型 | 说明 |
---|---|---|
id | Int | 焦点将要落在item的id |
name | String | 焦点将要落在item的name |
常见问题 Q&A
horizontal
、advancedFocusSearchSpan
、padding
属性不可动态改变,这三个在list-view初始化时就确定要实现
onItemClick
和onItemFocus
回调,需要在item中加上属性eventClick
和eventFocus
,这样才能让item响应点击和焦点事件
:scrollThresholdHorizontal
和:scrollThresholdVertical
属性的生效条件是:makeChildVisibleType='center'