akshathjain / sliding_up_panel

A draggable Flutter widget that makes implementing a SlidingUpPanel much easier!
https://pub.dartlang.org/packages/sliding_up_panel
Other
1.36k stars 378 forks source link

Help needed: Changing contents of panel after onPanelClosed not working. #229

Closed JaffaKetchup closed 3 years ago

JaffaKetchup commented 3 years ago

Hello all, I have a simple idea in my head: the panel can have two states, and swap between each by closing the panel, which then pops back open automatically.

Currently I have this code inside my SlidingUpPanel (abbreviated, only relevant code included):

minHeight: 20,
snapPoint: (90 /(((mainProps.panelMode != 'menu'? ((MediaQuery.of(context).size.height / 3) * 2) : MediaQuery.of(context).size.height) - 20) / 100)) / 100,
maxHeight: mainProps.panelMode != 'menu'? (MediaQuery.of(context).size.height / 3) * 2 : MediaQuery.of(context).size.height,
controller: pc,
backdropTapClosesPanel: false,
onPanelClosed: () {
        if (mainProps.panelMode != 'menu') {
          mainProps.panelMode = 'menu';
          pc.panelPosition = (90 /
                  (((mainProps.panelMode != 'menu'
                              ? ((MediaQuery.of(context).size.height / 3) * 2)
                              : MediaQuery.of(context).size.height) -
                          20) /
                      100)) /
              100;
        } else {
          mainProps.panelMode = 'scan';
          pc.panelPosition = (90 /
                  (((mainProps.panelMode != 'menu'
                              ? ((MediaQuery.of(context).size.height / 3) * 2)
                              : MediaQuery.of(context).size.height) -
                          20) /
                      100)) /
              100;
        }
},

, and I set the panel to be open using initialHeight from a fork on this repo. The same effect can be achieved by using the following code in the initState:

WidgetsBinding.instance.addPostFrameCallback((_) {
    pc.animatePanelToSnapPoint(duration: Duration(milliseconds: 0));
});

mainProps is my Provider state management solution. I decide the contents of the panel based on this. The large formula essentially gets the correct percentage for 90px height.

However, this produces an odd effect: https://user-images.githubusercontent.com/58115698/110238453-9be0da80-7f39-11eb-8dc3-eea3be3b0a6e.mp4

As you can see, if I drag the panel to closed state too quickly, the panel changes twice, meaning the content is the same as before. If I drag the panel slowly, the desired effect is created. I think this is due to the momentum caused by the SpringSimulation, however I could be wrong.

As an attempt to remedy this temporarily, I created the appropriate functions for the controller and animation controller to be able to reset (_ac.reset()) the animation (yes, I edited the cached package file (but this can be undone easily)). This, however, caused a stack overflow error when used as such:

mainProps.panelMode = 'menu';
pc.panelPosition = (90 /
    (((mainProps.panelMode != 'menu' ? ((MediaQuery.of(context).size.height / 3) * 2) : MediaQuery.of(context).size.height) - 20) / 100)) / 100;
pc.resetAnimation();

, or when used the pc.resetAnimation(); line is used before the panel position is set. I also tried with _ac.stop(), but this lead to the same issue.

Is there any way I can achieve my desired effect, bypassing this issue of the panel contents changing twice when the user swipes too quickly?

Thanks, Luka S.