GridView翻页实现
前言
使用GridView翻页让我折腾了一天,就是鼠标滑动一下,正好翻过去当前能看到的视图的一页,而不是随机停止,或者只是移动一个item,当然,如果只是翻页就简单了,问题是还要记录翻页后,当前的所在页面是第几页,这个就麻烦了。所幸,根据百度和Qt文档的不停地摸索,还是想出了一个勉强能维持得了效果的实现方法。
看一下效果图:
上面点击左右箭头也是可以跳转页面的,只是没有动画效果,但是页数还是在变,鼠标左右滑动,都能衔接的上,页面也能及时更新当前对页数
问题
其实最大的难点就是
- 如何鼠标移动的时候,移动的是一整块页面,而不是默认随机停止对位置,
- 如何点击按钮的时候,移动的是一整块页面,该移动和鼠标移动不是同一回事哦!!!
- 如何监听当前页面对变化,当然按钮点击自然好记录,点击一下就加一次,难点则在鼠标左右滑动上面如何记录,因为控件的滑动是监控不到的,要知道是左滑动还是右滑动更难。
解决的方案
有了上面提出的难点,自然一个个对攻克就ok呢。首先要做到的是按钮点击,实现按钮点击移动整块页面后,后续自然也好解决。
如何点击按钮移动呢?
百度是没办法了,我是没查找到有价值的文章,只能自己去看文档,有没有对应的方法,还别说,方法挺多(其实也就找到两个)如下图:
诺,就这两个方法,上面是按键导航的时候一个一个item跳的,如果要跳跃,循环4次(一页4列),调用4次即可直接跳转下一页,下面的positionViewAtIndex就厉害了,直接给index跳转,一次调用即可,所以自然是用positionViewAtIndex了,两种方法我都用过,看起来的效果都差不多,没有动画,直接跳转的,但是第一个实在麻烦,每次都要写个循环来跳转对应的次数,所以采用第二种方法即可,代码如下:
function moveGridView(direction) {
console.info("点击进来")
//点击左箭头翻页
if (direction === VehicleInformationGridViewBrowsing.ArrowDirection.LeftArrow) {
if (id_vehiclInfoViewRoot.currentPage == 0) {
id_vehiclInfoViewRoot.currentPage = id_vehiclInfoViewRoot.countPage - 1
} else {
id_vehiclInfoViewRoot.currentPage--
}
} //点击右箭头翻页
else if (direction === VehicleInformationGridViewBrowsing.ArrowDirection.RightArrow) {
if (id_vehiclInfoViewRoot.currentPage == id_vehiclInfoViewRoot.countPage - 1) {
id_vehiclInfoViewRoot.currentPage = 0
} else {
id_vehiclInfoViewRoot.currentPage++
}
}
id_listView.positionViewAtIndex(
id_vehiclInfoViewRoot.currentPage,
ListView.Beginning)
//下面这个可以填充一页不满足个数时自动填充对齐,有瑕疵,先屏蔽
// if(id_vehiclInfoViewRoot.currentPage == id_vehiclInfoViewRoot.countPage-1)
// {
// id_FGridView.positionViewAtIndex( id_FGridView.count-1,
// GridView.Beginning)
// }
}
说明一下,id_listView是个ListView,并不是GridView,这其中就要涉及到第一个难题了,要想鼠标翻页,就得用一个ListView来包含GridView直接翻页,而GridView是禁止交互对,达到对效果其实就是ListView在翻页,看上去是GridView在翻页而已。
看代码:
ListModel {
id: id_listModel
}
Component {
id: id_listDel
Rectangle {
width: id_listView.width
height: id_listView.height
color: "transparent"
//测试效果查看使用
// border.width: 3
// border.color: "black"
}
}
ListView {
id: id_listView
width: parent.width
height: parent.height - id_footerRect.height
model: id_listModel
delegate: id_listDel
orientation: ListView.Horizontal
snapMode: ListView.SnapOneItem
highlightRangeMode: ListView.StrictlyEnforceRange
onMovementEnded:
{
currentPage = id_listView.currentIndex
//对应上面对一页不满足个数时自动填充的问题,有瑕疵,先屏蔽
// if(id_vehiclInfoViewRoot.currentPage == id_vehiclInfoViewRoot.countPage-1)
// {
// currentPage = 6
// moveGridView(VehicleInformationGridViewBrowsing.ArrowDirection.RightArrow)
// }
}
}
//栅格视图显示
FGridView {
id: id_FGridView
width: parent.width
height: parent.height - id_footerRect.height
model: id_gridviewModel
interactive: false
contentX: id_listView.contentX
}
其中FGridView是我封装的一个GridView,重点是ListView的委托,而翻页的核心则是 contentX: id_listView.contentX这句话,当然 interactive: false,一定要是false,再看具体调用赋值的使用方法:
ListModel {
id: id_gridviewModel
Component.onCompleted: {
//对GridView进行数据处理
var nameText = ["风景1", "风景2", "吃鸡"]
for (var j = 0; j < 30; j++) {
for (var i = 0, count = QmlSingleton.slideImageUrl.length; i < count; i++)
id_gridviewModel.append({
"imageUrl": QmlSingleton.slideImageUrl[i],
"imageText": nameText[i] + j
})
}
//总页数
countPage = Math.round(id_FGridView.count / 12)
//对listview进行分页处理
for (j = 0; j < countPage; j++) {
id_listModel.append({
})
}
console.info("cacheBuff = ", id_FGridView.cacheBuffer)
}
}
基本上就是这些,翻页处理不过就是套用一个ListView而已!!!我显示的是左右翻页,上下翻页改变下X和Y的对应关系即可,这里不再啰嗦!
最后再贴出一个网上看的方案代码
Item {
width: 319
height: 150
Image {
id: image1
anchors.fill: parent
Item {
id: item1
anchors.rightMargin: 4
anchors.leftMargin: 3
anchors.bottomMargin: 4
anchors.topMargin: 27
anchors.fill: parent
ListView {
id: listView
anchors.fill: parent
model: listModel
delegate: listDel
orientation: ListView.Horizontal
snapMode: ListView.SnapOneItem
}
GridView {
id: gridView
anchors.fill: parent
model: gridModel
delegate: gridDel
cellHeight: height / 5 - 1
cellWidth: width
flow: Grid.TopToBottom
interactive: false
contentX: listView.contentX
}
}
}
Component {
id: gridDel
Item {
width: gridView.width
height: gridView.height / 5 - 1
Item {
anchors.centerIn: parent
width: gridView.width
height: gridView.height / 5 - 1
Text {
id: text2
anchors.centerIn: parent
font.pixelSize: 20
text: id
MouseArea {
id: mouse_area4
anchors.fill: parent
onClicked: {
text2.color = "#ffffff"
}
}
}
}
}
}
ListModel {
id: gridModel
}
Component {
id: listDel
Rectangle {
width: listView.width
height: listView.height
color: "transparent"
border.width: 3
border.color: "black"
}
}
ListModel {
id: listModel
}
Component.onCompleted: {
for (var i = 0; i < 100; ++i) {
gridModel.append({
"id": i
})
}
for (var j = 0; j < 50; ++j) {
listModel.append({
})
}
}
}