怎麼在Ubuntu QML應用中偵測到Swipe手勢,qmlswipe
我們知道在觸屏的手機中,可以利用手勢可以產生一下動作。特別是Ubuntu手機,手勢的操作利用的非常多。那麼怎麼可以在QML應用中偵測到手勢呢?我以前在我的Flickr應用使用到一個手勢的偵測。今天我們利用網上的一個常式來,做一個例子。這個常式更加具有可以重複利用性。我們的參閱代碼地址:https://gist.github.com/kovrov/1742405
SwipeArea.qml
/* This code was written by Sergejs Kovrovs and has been placed in the public domain. */import QtQuick 2.0MouseArea { property point origin property bool ready: false property int threshold: units.gu(20) signal move(int x, int y) signal swipe(string direction) onPressed: { drag.axis = Drag.XAndYAxis origin = Qt.point(mouse.x, mouse.y) } onPositionChanged: { switch (drag.axis) { case Drag.XAndYAxis: if (Math.abs(mouse.x - origin.x) > threshold ) { drag.axis = Drag.XAxis } else if (Math.abs(mouse.y - origin.y) > threshold) { drag.axis = Drag.YAxis } break case Drag.XAxis: move(mouse.x - origin.x, 0) break case Drag.YAxis: move(0, mouse.y - origin.y) break } } onReleased: { switch (drag.axis) { case Drag.XAndYAxis: canceled(mouse) break case Drag.XAxis: swipe(mouse.x - origin.x < 0 ? "left" : "right") break case Drag.YAxis: swipe(mouse.y - origin.y < 0 ? "up" : "down") break } }}
這裡的代碼定義了一個新的MouseArea的Component。這個Component可以在任何其它需要用到MouseArea的地方用到。你也可以理解為MouseArea的重載(從C++的角度,雖然並不精確)。我們對原作者的代碼沒有更多的改動,但是,我重新定義了一個“threshold”。這個是用來調整我們的Swipe的靈敏度的。比如,一個較大的值,使得我們必須使用較大的滑動才可以產生swipe的訊號。較小的值,使得swipe的偵測更加容易。這個可以根據我們在實際的應用中進行調整。
那麼我們如何使用這個SwipeArea的Component呢?
Swipe.qml
/* This code was written by Sergejs Kovrovs and has been placed in the public domain. */import QtQuick 2.0Item { id: root width: 480 height: 320 property var itemData: ["#22eeeeee", "#22bbbbbb", "#22888888", "#22555555", "#22222222"] property int currentIndex: 0 onCurrentIndexChanged: { slide_anim.to = - root.width * currentIndex slide_anim.start() } PropertyAnimation { id: slide_anim target: content easing.type: Easing.OutExpo properties: "x" } Image { id: img anchors.verticalCenter: root.verticalCenter source: "images/wallpaper.jpg" fillMode: Image.PreserveAspectCrop } Item { id: content width: root.width * itemData.length property double k: (content.width - root.width) / (img.width - root.width) onXChanged: { img.x = x / k// console.log("img.x: " + img.x ); } Repeater { model: itemData.length Rectangle { x: root.width * index width: root.width; height: root.height color: itemData[index] Text { text: index+1; anchors.centerIn: parent; font.pointSize: 100; color: "#88000000" } } } } SwipeArea { id: mouse anchors.fill: parent onMove: { content.x = (-root.width * currentIndex) + x// console.log("content.x " + content.x); } onSwipe: { switch (direction) { case "left": if (currentIndex === itemData.length - 1) { currentIndexChanged() } else { currentIndex++ } break case "right": if (currentIndex === 0) { currentIndexChanged() } else { currentIndex-- } break } } onCanceled: { currentIndexChanged() } } Row { anchors { bottom: parent.bottom; bottomMargin: 16; horizontalCenter: parent.horizontalCenter } spacing: 16 Repeater { model: itemData.length Rectangle { width: 12; height: 12; radius: 6 color: currentIndex === index ? "#88ffffff" : "#88000000" border { width: 2; color: currentIndex === index ? "#33000000" : "#11000000" } } } }}
就像我們正常情況下使用MouseArea的情況一樣,我們可以在我們需要偵測滑動的地方使用SwipeArea。這樣,我們只需要捕獲SwipeArea中發出的訊號:
SwipeArea { id: mouse anchors.fill: parent onMove: { content.x = (-root.width * currentIndex) + x// console.log("content.x " + content.x); } onSwipe: { switch (direction) { case "left": if (currentIndex === itemData.length - 1) { currentIndexChanged() } else { currentIndex++ } break case "right": if (currentIndex === 0) { currentIndexChanged() } else { currentIndex-- } break } } onCanceled: { currentIndexChanged() } }
這裡,我們可以捕獲onSwipe就可以得到Swipe的方向。在本例子中,我們只對左右感興趣。我們可以通過手勢向左或向右滑動來看一個圖片的其它的部分。
整個測試專案的源碼在:git clone https://gitcafe.com/ubuntu/swipe.git