Flickable
?是 QML 中用于創建可滾動區域的基礎組件,它比?ScrollView
?提供更底層的控制,適合需要自定義滾動行為的場景。
基本用法
qml
import QtQuick 2.15Flickable {width: 200height: 200contentWidth: 400 // 內容總寬度contentHeight: 800 // 內容總高度// 內容項Rectangle {width: 400height: 800gradient: Gradient {GradientStop { position: 0.0; color: "red" }GradientStop { position: 1.0; color: "blue" }}}
}
Flickable 屬性表
1. 核心屬性
屬性 | 類型 | 默認值 | 說明 |
---|---|---|---|
contentWidth | real | 0 | 必須設置?- 內容區域的總寬度 |
contentHeight | real | 0 | 必須設置?- 內容區域的總高度 |
contentX | real | 0 | 當前水平滾動位置(可讀寫) |
contentY | real | 0 | 當前垂直滾動位置(可讀寫) |
clip | bool | false | 是否裁剪超出部分(建議設為?true ) |
interactive | bool | true | 是否允許用戶交互滾動 |
2. 滾動行為控制
屬性 | 類型 | 默認值 | 說明 |
---|---|---|---|
boundsBehavior | enum | Flickable.StopAtBounds | 邊界行為:StopAtBounds ?- 不能拖出邊界DragOverBounds ?- 可拖出邊界(有回彈)OvershootBounds ?- 允許短暫超出 |
flickableDirection | enum | AutoFlickDirection | 滾動方向:HorizontalFlick ?- 僅水平VerticalFlick ?- 僅垂直HorizontalAndVerticalFlick ?- 雙向AutoFlickDirection ?- 自動判斷 |
maximumFlickVelocity | real | 2500 | 最大滾動速度(像素/秒) |
flickDeceleration | real | 1500 | 滾動減速系數(值越大停止越快) |
pressDelay | int | 0 | 觸摸按下延遲(毫秒) |
3. 只讀屬性
屬性 | 類型 | 說明 |
---|---|---|
dragging | bool | 是否正在拖動 |
flicking | bool | 是否正在慣性滾動 |
moving | bool | 是否正在移動(拖動或慣性滾動) |
visibleArea | object | 包含:widthRatio ?- 可見寬度比例heightRatio ?- 可見高度比例xPosition ?- 水平位置(0.0-1.0)yPosition ?- 垂直位置(0.0-1.0) |
4. 信號
信號 | 參數 | 說明 |
---|---|---|
movementStarted() | - | 開始滾動時觸發 |
movementEnded() | - | 滾動停止時觸發 |
flickStarted() | - | 慣性滾動開始時觸發 |
flickEnded() | - | 慣性滾動結束時觸發 |
contentXChanged() | real | 水平位置變化時觸發 |
contentYChanged() | real | 垂直位置變化時觸發 |
5. 常用方法
方法 | 參數 | 說明 |
---|---|---|
flick(vx, vy) | vx : 水平速度vy : 垂直速度 | 以指定速度觸發慣性滾動 |
cancelFlick() | - | 立即停止慣性滾動 |
returnToBounds() | - | 強制回到邊界內 |
完整示例代碼
import QtQuick 2.15Flickable {id: flickwidth: 300height: 400contentWidth: contentItem.widthcontentHeight: contentItem.heightclip: trueboundsBehavior: Flickable.DragOverBounds// 內容項Grid {id: contentItemwidth: 600height: 800columns: 3spacing: 10Repeater {model: 50Rectangle {width: 180; height: 180color: Qt.hsla(index/50, 0.8, 0.6, 1)Text { text: index; anchors.centerIn: parent }}}}// 監聽滾動onContentYChanged: console.log("Y位置:", contentY)onMovementEnded: console.log("滾動停止")// 滾動到指定位置function scrollToBottom() {contentY = contentHeight - height}
}
?
滾動行為控制
qml
Flickable {// 啟用水平和垂直滾動flickableDirection: Flickable.HorizontalAndVerticalFlick// 允許拖動超出邊界(會有回彈效果)boundsBehavior: Flickable.DragOverBounds// 滾動速度系數flickDeceleration: 1500// 最大速度限制maximumFlickVelocity: 2500
}
與 ScrollBar 配合使用
qml
import QtQuick 2.15
import QtQuick.Controls 2.15Flickable {id: flickwidth: 200height: 200contentWidth: 400contentHeight: 800// 內容項...// 垂直滾動條ScrollBar.vertical: ScrollBar {policy: ScrollBar.AsNeededsize: flick.height / flick.contentHeightposition: flick.visibleArea.yPosition}// 水平滾動條ScrollBar.horizontal: ScrollBar {policy: ScrollBar.AsNeededsize: flick.width / flick.contentWidthposition: flick.visibleArea.xPosition}
}
可見區域計算
qml
Flickable {// 獲取可見區域比例和位置property real visibleWidthRatio: visibleArea.widthRatioproperty real visibleHeightRatio: visibleArea.heightRatioproperty real visibleXPosition: visibleArea.xPositionproperty real visibleYPosition: visibleArea.yPosition
}
高級用法
1. 滾動到指定位置
qml
// 滾動到水平中心
flick.contentX = (flick.contentWidth - flick.width) / 2// 帶動畫效果
NumberAnimation {target: flickproperty: "contentX"to: targetValueduration: 500easing.type: Easing.InOutQuad
}.start()
2. 嵌套 Flickable
qml
Flickable {// 外部FlickableFlickable {// 內部Flickable// 需要處理事件傳遞onMovementStarted: parent.flickableDirection = Flickable.HorizontalFlickonMovementEnded: parent.flickableDirection = Flickable.AutoFlickDirection}
}
3. 下拉刷新實現
qml
Flickable {id: flickonMovementEnded: {if (contentY < -refreshThreshold) {// 觸發刷新}}Rectangle {// 刷新指示器y: -heightvisible: flick.contentY < 0}
}
性能優化技巧
-
啟用裁剪:
qml
Flickable {clip: true }
-
動態加載內容:
qml
Flickable {// 只加載可視區域內容Loader {visible: y >= flick.contentY && y <= flick.contentY + flick.height} }
-
減少過度繪制:
qml
Flickable {layer.enabled: truelayer.textureSize: Qt.size(width, height) }