Unsolved SwipeView page change without animation
-
Hi,
I have a SwipeView of 10 pages, also I have 10 page indicator at the bottom. Every page indicator corresponds to a page of swipeView. On clicking first page indicator, the first page of swipeview should be the currentItem and so on till 10 pages.
Suppose , the currentItem is the first page and now that, I click on 10th page indicator, the current item changes to 10th page. Well, my problem is the transition from 1st page to 10th page, an animation that slides through 2,3,4.....,7,8,9 pages to reach 10th page. How can I disable this transition so that, I can reach 10th page in a blink.
Sample code for your reference.
SwipeView { id: view currentIndex: 0 anchors.fill: parent Rectangle { id: firstPage color: "red" } Rectangle { id: secondPage color: "blue" } Rectangle { id: thirdPage color: "green" } Rectangle { id: fourthPage color: "pink" } Rectangle { id: fifthPage color: "yellow" } Rectangle { id: sixthPage color: "gray" } } PageIndicator { id: indicator count: view.cou nt currentIndex: view.currentIndex delegate: Rectangle{ width: 30 height: 30 radius: 15 color: "black" MouseArea{ anchors.fill: parent onClicked: { view.currentIndex = index } } } anchors.bottom: view.bottom anchors.horizontalCenter: parent.horizontalCenter }
-
I think the only way (if you want to stick to SwipeView) might be to use Loader approach, which is outlined at the end of SV description in the docs.
-
@sierdzio Thanks for the reply.
Well, that doesn't work for me. With loader, there is transition animation with an empty white page in between. All I want is to disable swipe animation when I purposefully change currentIndex to directly skip to that page. -
Then I think there is no way to do it currently with SwipeView. It is, however, doable with custom ListView with
snapTo
property set.QtQuick.Controls 2 are still quite new, I suggest you file in a feature request on Qt bugtracker to add more control over SwipeView animation.
-
@Yashpal
you can simply create your own custom swipeview by implementing a SwipeArea (e.g. like this) and a StackView element -
-
@Marek I had a working module using ListView with snapMode:
ListView.SnapOneItem but then still, I wanted to try with SwipeView. Unfortunately, I couldn't try SwipeArea and StackView. I definitely want to try this, hopefully in my free time and let you know. -
@Yashpal I'm using StackView with SwipeArea, but I have this SwipeArea on each page of StackView. Thats the only way I could make it work.
-
@Marek Cool. Good to hear that. If possible, please can you share code for the same.
-
@Yashpal ok, it's Qt Quick 2, and I'm changing transition, so new page is sliding from left or right side of the screen depending of what I need and I'm using stackView.replace, so I have always one item on the stack
//part of main.qml Page1 { id: homePage } //.... other pages ...// TestPage { id: testPage visible: false } StackView { id: stackView anchors.top: menuItem.bottom anchors.bottom: parent.bottom width: parent.width property int direction: 1 property int in_x_from: mainRect.width property int in_x_to: 0 property int out_x_from: 0 property int out_x_to: -mainRect.width replaceEnter: Transition { id: replaceEnter ParallelAnimation { PropertyAnimation { property: "x" from: stackView.in_x_from to: stackView.in_x_to duration: 200 } PropertyAnimation { property: "opacity" from: 0 to: 1 duration: 200 } } } replaceExit: Transition { id: replaceExit ParallelAnimation { PropertyAnimation { property: "x" from: stackView.out_x_from to: stackView.out_x_to duration: 200 } PropertyAnimation { property: "opacity" from: 1 to: 0 duration: 200 } } } function changeTransitionDirection(dir) { if(dir==1) { stackView.direction= 1 stackView.in_x_from= mainRect.width stackView.in_x_to= 0 stackView.out_x_from= 0 stackView.out_x_to= -mainRect.width } else { stackView.direction= 1 stackView.in_x_from= -mainRect.width stackView.in_x_to= 0 stackView.out_x_from= 0 stackView.out_x_to= mainRect.width } } Component.onCompleted: { stackView.push(homePage) } } //TestPage.qml Rectangle { id: testPage width: parent.width Flickable { id: flickable anchors.fill: parent flickableDirection: Flickable.VerticalFlick contentHeight: testPage.height contentWidth: testPage.width clip: true focus: true Rectangle { //main page rect, where I keep "things" which should be siblings to SwipeMouseArea with higher "z" value, otherwise SwipeMouseArea is stealing events even with preventStealing: true id: rectangle anchors.fill:parent anchors.margins: 40 color: "black" SwipeMouseArea { z:1 id: swipeMouse anchors.fill: parent preventStealing: false propagateComposedEvents: true onSwipeRight: { someSignal() } onSwipeLeft: { someOtherSignal() } } } } } //SwipeMouseArea.qml MouseArea { id: mouse // preventStealing: true propagateComposedEvents: true property real velocity: 0.0 property int xStart: 0 property int xPrev: 0 property int yPrev: 0 property bool tracing: false property bool swiping: false signal swipeLeft() signal swipeRight() onPressed: { xStart = mouse.x xPrev = mouse.x velocity = 0 tracing = true swiping = false console.log("SwipeMouseArea mouse pressed"); } onPositionChanged: { if ( !tracing ) return var currVel = (mouse.x-xPrev) velocity = (velocity + currVel)/2.0 xPrev = mouse.x console.log("SwipeMouseArea vel:"+velocity) if ( velocity < -5 ) { tracing = false swiping=true console.log("SwipeMouseArea left swipe"); swipeLeft() } if ( velocity > 5 ) { tracing = false swiping=true swipeRight() console.log("SwipeMouseArea right swipe") } } onReleased: { tracing = false } }
-
Although this is an old post, the solution to the original question can be found here.
You can do the following to disable animations when programmatically setting the index of the
SwipeView
:SwipeView { id: view function positionViewAtIndex(idx) { var tmp = view.contentItem.highlightMoveDuration //or save this orig. value only once somewhere higher up view.contentItem.highlightMoveDuration = 0 view.currentIndex = idx view.contentItem.highlightMoveDuration = tmp } ... }
That works as desired.