Pages, Back Button and "Slide" Animation
-
Hi all,
There is a kind of app that is very common on mobile devices like Android and iPhone. They have a standard header that includes the title and a back button and the user can navigate through the various pages and press the back button to return to the previous page. Generally, when a new page is loaded it slides in to view from right to left and when the back button is pressed the page slides out from left to right making way for the previous page. I don't know about iOS but on Android this is all done by the OS - I don't have to worry about animation or keeping a stack of pages or anything like that.
I see now that Qt Quick is released there still isn't a built-in solution for this which is surprising as it is such a common pattern. It seems like QML is designed for a different kind of app - an app that has one big canvas with lots of moving parts. For typical page-based apps, it falls short. Or am I missing something?
What I need specifically, is the ability to switch pages using a "Slide left" transition when loading new pages and a "Slide Right" transition when going back by pressing the back button. I could easily achieve this with states/transitions as long as I keep all the pages in memory but I've had issues with that when running on devices - pages tend to slow down the more I add. A typical app will have about 20 pages.
So I need to use Loaders and that is fine if I am willing to give up the fancy slide transitions but it would be a shame to loose them. I think users kind of expect the animations these days and having fancy graphics/animations is one of the main reasons I use QML in the first place!
I am writing this post to get some feedback on whether I am right or whether I have missed something. Could someone confirm or deny whether it's possible to have slide transitions with Loaders in QML without resorting to C++? I don't mind dropping into C++ if I have to but ideally I'd like to keep all the UI in QML if possible for obvious reasons.
If the answer is no I will write a C++ component to achieve the desired results. I already have something in C++ that works but it's buggy and difficult to use - it feels like a hack to be honest. If I have no other choice I will go back to it and try to clean it up.
Thank you,
Paul Drummond -
I've done page translations with Loaders by using a pair of loaders, one which holds the current page, and one that holds the page I want to load. I wrapped them into a parent Item which I use to control the logic for choosing the active loader and the secondary loader (they alternate -- after the new page transitions in, I can unload the old page and prep it for the next item.) I've used it for dissolve transitions using an animation on the opacity property across both loaders, but it would be just as easy to position the secondary loader offscreen, and then toggle the transition once the page is loaded using animations on the X properties of both loaders.
There's a little bit of code that has to be written in the parent item for handling the logic of the Loader pool, but it's fairly straightforward.
-
@mlong - I attempted something similar but I couldn't get it to work properly for my requirements (sliding transition and maintaining a list of pages in a stack).
I have two loaders - loader1 represents the "onScreen" at pos 0,0 and loader2 represents the "offScreen" at pos 360,0. When I load a page, I have some js that adds the current page name (if there is one) to the stack then slides loader1 off screen while sliding loader2 on screen.
Then I hit my first problem - how do I detect when the animation is finished? I used onRunningChanged in PropertyAnimation but it felt wrong. Anyway, I then had a bit of js code to swap the loader1 with loader2.
So at this point the sliding is complete and the new page is displayed. But the original page (now loader2) is offscreen at pos -360 and I need to re-position it's original position which is offscreen to the right at x=360. How do I do that? I can't change the x value because that will cause the animation to start which will cause the onRunningChanged to fire again! I could add a flag or something but I think this solution is already quite a hack to be honest. Even if I got this to work it only covers the "left-to-right" sliding. I also need to support sliding the opposite way for when the back button is pressed.
So this is when I gave up and decided the only option is to write a C++ "Pager". I thought I'd try getting some feedback on this forum before I dived in though...
-
In my case I have only about 8 screens and I know I'll have a maximum depth of 5. So I created a ListView and a VisualItemModel. The model holds 5 loaders for 5 screens.
In this case you'll get all the animation stuff for free. All you have to do is call view.currentIndex++. Of course you also need to make sure to load the next required screen into the loader on the right side of the current loader.
The only problem I have with this approach is that if I load a complex screen, the sliding animation is stuttering a bit. At least on a N900.
-
Incidentally, as for how to tell when an animation is done, if you don't want to rely on the onRunningChanged method, you can always wrap your PropertyAnimation inside of a SequentialAnimation and add a ScriptAction immediately after it which could emit some sort of signal.
-
Hi ,
If i understood correctly your query , you need some kind of QT QUICK support to get those transitions automatically which you move forward or backward in deep linked pages.
Well, there are these PageStack and Page components which does this fairly easiy and simple way.
PageStack keeps all the the linked pages in stack and as you push or pop pages, transitions are automatically created the way you explained it.Let me know if this answered your question
-
Hi anwar,
Sorry for the late response - I've been away from this issue for a while but I'm back on it now.
Google tells me that PageStack and Page are part of the Qt Quick Components project. From looking at the source it looks like exactly what I need!
I've asked about the status of this project a few times now but I haven't had any solid responses. Does anyone here know what the status is? Can we use the PageStack component in our projects now? Will the API's change going forward? Will this project ever be released?
I also tried creating my own C++ pager and it works well in the simulator but when I run it on a device I get a SIGSEGV and the debugger tells me it is on the line that starts the "slide" animation. I am using QParallelAnimationGroup to slide both the original screen and the new screen at the same time.
It's very frustrating that this works fine in the simulator and on the desktop. It only crashes on the device.
I think I will have to resort to using Loaders and forget about "slide-in" transitions for now. :-(
-
You could just try and see if the components work properly for you as they are. If it does what you need, you just keep using the current version (if the licence allows you to, you have to check that yourself).
It certainly is annoying if something works on the desktop and not on the device. That is hard to fix.
-
Hi Prummond ,
I have used PageStack and Page, and works absolutely as expected. I think the docs shall be made public sometime today...you can get the docs from
https://gitorious.org/+doc-qt-components/doc-qt-componentsAs far as APIs are concerned to my knowledge they are frozen
Entire package is being released with new version of QT Components and shall be released either today or tomorrow. Also there is a plugin being released for QT SDK too.
I think worth waiting for few more days could save your time and effort.
You can check the QT Components code also from gitorious. -
Well this is perfect timing for me:
http://labs.qt.nokia.com/2011/04/08/qt-quick-components-for-symbian-technology-preview/
I need to check it out a bit more but I think PageStack is exactly what I need. I wonder if it uses Loaders?
I am also wondering if it's possible to customise the look and feel or whether I would be stuck with the Symbian native look and feel.
Finally, I presume that even if these components aren't officially released in time for the release of my app, then there would be no problem just including the qt-component libs in my SIS or maybe just directly including the source.
Paul.