Comment 14 for bug 1572525

Revision history for this message
Tim Peeters (tpeeters) wrote : Re: [regression] Double header height is set as flickable topMargin

The desired behavior in your video can easily be accomplished by keeping your old code, and NOT setting the flickable of the PageHeader. Actually I think that is the best solution for the users too because otherwise the header may be showing/hiding while you swipe left/right.

About your proposal,
1) I think nobody disagrees with that
2) I think the use case you mention where the topMargin is maintained when the header is hidden conflicts with this. In this case, I interpret the hidden header as a header that goes away by scrolling, so its exposed property becomes false. The header should *not* change the topMargin when exposed changes, because changes in topMargin may change exposed again, and it will cause the page contents to jump around when the header hides.

Another issue with 2) is the implementation. It means that when you unset a header.flickable, it will restore the previous topMargin. So what happens when you have this case (which happens in practice when apps have multiple headers on a Page (for example an edit header and a regular header, of which only one is visible).

Say, we have this QML code:
Page {
   id: page
  PageHeader { id: header1; visible: page.header==header1; flickable: pageFlickable }
  PageHeader { id: header2; visible: page.header==header2; flickable: pageFlickable }
  header: editMode ? header2 : header1
  property bool editMode: false

  Flickable { id: pageFlickable }
}

Internally, header1 and header2 have a property "previousHeaderHeight" that they use to restore the previous header height when flickable is unset or the header becomes invisible.
Let's assume that header1 is always updated first by the qml engine, and then header2 (that happened in my case).

1. editMode = true
// header 1 first reverts the previous header height
// header1: visible = false; pageFlickable.topMargin = 0;
// header2: visible = true; previousHeaderHeight = 0; pageFlickable.topMargin = header2.height;

2. editMode = false
// header1: visible = true; previousHeaderHeight = header2.height; pageFlickable.topMargin = header1.height;
// header2: visible = false; pageFlickable.topMargin = 0 (previousHeaderHeight);

So now we have the wrong topMargin because we don't know in which order the properties of the different headers will be updated. The solution to this is to make the headers not store previousHeaderHeight, or to set the topMargin to header.height but to add to the topMargin when a header is enabled with a flickable, and subtract the header height from it when the header is invisible or the flickable is unset.