QML 中GridView翻页实现

前言

使用GridView翻页让我折腾了一天,就是鼠标滑动一下,正好翻过去当前能看到的视图的一页,而不是随机中止,或者只是移动一个item,固然,若是只是翻页就简单了,问题是还要记录翻页后,当前的所在页面是第几页,这个就麻烦了。所幸,根据百度和Qt文档的不停地摸索,仍是想出了一个勉强能维持得了效果的实现方法。
看一下效果图:
在这里插入图片描述
上面点击左右箭头也是能够跳转页面的,只是没有动画效果,可是页数仍是在变,鼠标左右滑动,都能衔接的上,页面也能及时更新当前对页数web

问题

其实最大的难点就是app

  1. 如何鼠标移动的时候,移动的是一整块页面,而不是默认随机中止对位置,
  2. 如何点击按钮的时候,移动的是一整块页面,该移动和鼠标移动不是同一回事哦!!!
  3. 如何监听当前页面对变化,固然按钮点击天然好记录,点击一下就加一次,难点则在鼠标左右滑动上面如何记录,由于控件的滑动是监控不到的,要知道是左滑动仍是右滑动更难。

解决的方案

有了上面提出的难点,天然一个个对攻克就ok呢。首先要作到的是按钮点击,实现按钮点击移动整块页面后,后续天然也好解决。
如何点击按钮移动呢?
百度是没办法了,我是没查找到有价值的文章,只能本身去看文档,有没有对应的方法,还别说,方法挺多(其实也就找到两个)以下图:
在这里插入图片描述
诺,就这两个方法,上面是按键导航的时候一个一个item跳的,若是要跳跃,循环4次(一页4列),调用4次便可直接跳转下一页,下面的positionViewAtIndex就厉害了,直接给index跳转,一次调用便可,因此天然是用positionViewAtIndex了,两种方法我都用过,看起来的效果都差很少,没有动画,直接跳转的,可是第一个实在麻烦,每次都要写个循环来跳转对应的次数,因此采用第二种方法便可,代码以下:ide

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在翻页而已。
看代码:svg

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({

                                 })
            }
        }
    }