QML ListView 实现下拉刷新 上拉加载

1. 简述

QML 中ListView没有自带这个功能,但是提供了自定义页头和页脚组件,控制组件有无,实现下拉刷新和上拉加载。刷新委托和加载委托支持用户完全自定义。
请添加图片描述

2. 代码

2.1 PullListViewV2.qml

import QtQuick

ListView {
    id: listView

    property bool headerVisible: false
    property bool footerVisible: false
    property bool headerHold: false
    property bool footerHold: false

    enum MoveDirection{
        NoMove,
        UpToDown,
        DownToUp
    }
    property int moveDirection: PullListViewV2.NoMove
    property real moveStartContentY: 0

    onHeaderVisibleChanged: if(!headerVisible) {headerHold = false}
    onFooterVisibleChanged: if(!footerVisible) {footerHold = false}
    onContentYChanged: {
        if(dragging || flicking)
        {
            moveDirection = (contentY - moveStartContentY < 0) ? PullListViewV2.UpToDown : PullListViewV2.DownToUp
//            console.log("onContentYChanged:",atYBeginning,moveDirection,headerVisible)
            switch(moveDirection){
            case PullListViewV2.UpToDown:{
                if(atYBeginning && !headerVisible && !footerVisible) {
                    headerVisible = true
                }
            }break;
            case PullListViewV2.DownToUp:{
                if(atYEnd && !headerVisible && !footerVisible) {
                    footerVisible = true
                }
            }break;
            default:break;
            }
        }
    }

    //鼠标或手指拖动驱动的界面滚动
    onDraggingChanged: dragging ? pullStart() : pullEnd()
    //鼠标滚动驱动的view滚动
    onFlickingChanged: flicking ? pullStart() : pullEnd()

    function pullStart(){
        console.log("pullStart")
        moveStartContentY = contentY
    }

    function pullEnd(){
//        console.log("pullEnd:",atYBeginning,moveDirection,headerVisible,contentY - moveStartContentY)

        switch(moveDirection){
        case PullListViewV2.UpToDown:{
            if(atYBeginning && headerVisible) {
                headerHold = true
            }else if(null !== headerItem){
                headerVisible = false
                headerHold = false
            }

        }break;
        case PullListViewV2.DownToUp:{
            if(atYEnd && footerVisible) {
                footerHold = true
            }else if(null !== footerItem){
                footerVisible = false
                footerHold = false
            }
        }break;
        default:break;
        }

        moveDirection = PullListViewV2.NoMove
    }
}

2.2 main.qml

import QtQuick

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
	
	Item{
	    anchors.fill: parent
	
	    PullListViewV2{
	        id: listView
	        anchors.fill: parent
	        model: listModel
	        delegate: Item {
	            id: name
	            height: 40
	            width: listView.width
	
	            Rectangle{
	                anchors.fill: parent
	                anchors.margins: 4
	                color: "red"
	                radius: 4
	                Text{
	                    anchors.verticalCenter: parent.verticalCenter
	                    anchors.leftMargin: 6
	                    anchors.left: parent.left
	                    text: "行:" + index
	                }
	            }
	        }
	
	        Component{
	            id: cmpHeader
	            Rectangle{
	                color: "yellow"
	                width: listView.width
	                height: 16
	                Text{
	                    anchors.centerIn: parent
	                    text: listView.headerHold ? "正在刷新" : "刷新"
	                }
	            }
	        }
	        header: headerVisible ? cmpHeader : null
	        onHeaderHoldChanged:{
	            if(headerHold)
	                timerRefresh.start()
	        }
	
	        Component{
	            id: cmpFooter
	            Rectangle{
	                color: "yellow"
	                width: listView.width
	                height: 16
	                Text{
	                    anchors.centerIn: parent
	                    text: listView.footerHold ? "正在加载..." : "加载更多"
	                }
	            }
	        }
	        footer: footerVisible ? cmpFooter : null
	        onFooterHoldChanged: {
	            if(footerHold)
	                timerLoadMore.start()
	        }
	    }
	
	    //刷新
	    Timer{
	        id: timerRefresh
	        interval: 1000
	        onTriggered: {
	            console.log("刷新完成")
	            listModel.refresh()
	            listView.headerVisible = false
	        }
	    }
	
	    //加载
	    Timer{
	        id: timerLoadMore
	        interval: 1000
	        onTriggered: {
	            console.log("加载完成")
	            listModel.loadMore()
	            listView.footerVisible = false
	        }
	    }
	    ListModel{
	        id: listModel
	
	        function refresh(){
	            listModel.clear()
	            for(var i = 0; i < 10; i ++){
	                listModel.append({name:listModel.count + 1})
	            }
	        }
	        function loadMore(){
	            for(var i = 0; i < 5; i ++){
	                listModel.append({name:listModel.count + 1})
	            }
	        }
	
	        function canLoadMore(){
	            return count > 30 ? false : true;
	        }
	
	        Component.onCompleted: refresh()
	    }
	}
}

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Qt QML 提供了一个名为 ListView 的组件,可以用于显示列表视图,支持下刷新、上分页和滚动轴。 以下是一个简单的 ListView 示例: ``` import QtQuick 2.0 import QtQuick.Controls 2.0 ApplicationWindow { visible: true width: 400 height: 600 title: "ListView Example" ListView { id: listView anchors.fill: parent // 设置模型数据 model: ListModel { ListElement { name: "Item 1" } ListElement { name: "Item 2" } ListElement { name: "Item 3" } ListElement { name: "Item 4" } ListElement { name: "Item 5" } ListElement { name: "Item 6" } ListElement { name: "Item 7" } ListElement { name: "Item 8" } ListElement { name: "Item 9" } ListElement { name: "Item 10" } } // 设置每个项的属性 delegate: Rectangle { width: listView.width height: 50 color: index % 2 == 0 ? "#f2f2f2" : "#ffffff" Text { text: name anchors.centerIn: parent } } // 下刷新 onRefreshRequested: { console.log("下刷新") } // 上分页 onEndReached: { console.log("上分页") } // 滚动轴 ScrollBar.vertical: ScrollBar {} } } ``` 上面的示例中,ListView 的 model 属性设置了一个 ListModel,用于存储模型数据。delegate 属性则定义了每个项的属性,包括宽度、高度、颜色和文本。 在 ListView 中可以通过 onRefreshRequested 和 onEndReached 信号来实现刷新和上分页功能。当用户下列表视图时,会触发 onRefreshRequested 信号;当滚动到列表视图底部时,会触发 onEndReached 信号。 最后,为了实现滚动轴,我们可以在 ListView 中添 ScrollBar 组件,设置其 vertical 属性为 true 即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是唐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值