среда, 21 октября 2015 г.

Implementation of a slide menu in QML


In my first note I'd like to show you how to implement a slide menu by using QML. These sorts of menu we often can see in many Android apps and sometimes on web sites. We can search for hundreds of examples how to implement it.
 Here we are going to talk about an implementation of a menu when the layer of it is located above the surface of the main screen. It's a very common case and it can be found in many and many Android applications. You can see an example of it in this video


 First of all, you need to have a possibility to pull out your menu from the left side whatever your app has on its surface. The surface can have buttons or any flickable items such as ListView or GridView. Let's have a look on source code.



Here is an example of a QML file with a slide menu.
 First of all we need to consider properties of the menu which somehow describe its state and help to interact with other elements of your app.
  • durationOfMenuAnimation - it's a quite understandable property which describes how fast the menu opens by pressing on a menu button.
  • menuWidth - describes the width of the menu.
  • widthOfSeizure - this is a very interesting property. It describes the width of area from the left side which allows you to pull out the menu.
  • menuIsShown - it's a logical variable shows the state of the menu.
  • menuProgressOpening - shows how much the menu is being open. It changes between 0 (the menu is fully closed) and 1 (the menu is fully open)
 Let's start consideration how it works. Here we have three main fragments:
  • a top bar
  • the menu
  • a loader
Those three components form the main screen of our app.


The top bar contains the menu button. We will consider it a little later. As we can see, initially the menu is shifted to the left for a whole width.

 x: -menuWidth

The area at the left side of the screen is a mouse area which is attached to the right side of the menu so we can pull out the menu by using the MouseArea. Each time when we release the MouseArea this fragment decides whether the menu will be closed again or fully open.


If the menu was released on less than a half way it would return to the previous state. It will be closed. If it was pulled out more than a half way, it would be fully open. This behaviour exactly repeats an action what all similar menus do.
 Whenever the menu is open the MouseArea expands until the right side of the screen.

width: app.menuIsShown ? (app.width - menuWidth) : widthOfSeizure

so a user can tap on any area outside of the menu and it will be closed. You can see that on the picture below



or it's also possible to tap on the menu button. If a user taps on it a function onMenu() is being called. It checks whether the menu is open or not and just changes its position by x.
 The property menuProgressOpening just helps to change the menu button simultaneously with its moving. It changes from 0 to 1. 
 The main idea of the button was taken from this project. I just changed that code to make the button follow changing of menu position. 
 Here is a short video of this menu showing how it works.

The source code of the project can be found on Githib. Any questions and notes are always welcome.


5 комментариев:

  1. Огромное спасибо за подробное руководство!
    Уверен, он будет на пользу ещё многим, пишите пожалуйста больше таких статей!

    ОтветитьУдалить
  2. Thanks for this nice work. I just want to make a feature request.
    Is it possible to swipe the menu out and in by swiping on the list view?
    the list view responds to up and down swipe but does not closes or opens
    the slide menu.

    ОтветитьУдалить
    Ответы
    1. Hi, with this implementation you can't actually drag the menu to the left. This feature needs to be implemented.

      Удалить
  3. Sorry the above behaviour is only on mobile platform (Android)

    ОтветитьУдалить
  4. Video of the problem:

    https://drive.google.com/file/d/0B4yfAVMLmbQxTDk1ZkdZWm1wU0E/view?usp=sharing

    ОтветитьУдалить