Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Janky animation when navigating away from variable-height stateful widget #184

Open
auradigitaldev opened this issue Apr 19, 2024 · 3 comments
Labels
bug Something isn't working in triage

Comments

@auradigitaldev
Copy link

Bug report

Describe the bug
First off, I love WoltModalSheet, it makes multi-page modals so easy!

However, I've been running into a pretty rough issue - whenever changing between modal pages where the first modal page is a StatefulWidget that varies in height based on its state, the animation between modals becomes extremely janky.

  • The modal will smoothly transition to a height that seems based on the difference in height between the StatefulWidget's default state and current state
  • Then the modal will abruptly snap to the height of the new modal page.

Here's a video to illustrate. At 0:08 I change the height of the first modal and then navigate to the second modal, which shows the bug:

screen-20240419-152521.mp4

Steps to reproduce

Steps to reproduce the behavior:

  1. Have a multi-page modal where the first page is a stateful widget whose height depends on its own state
  2. Update the height of the stateful widget
  3. Navigate to the next page of the multi-page modal
  4. Observe bug

Expected behavior

Expected to see a smooth transition between the heights of the current modal page and the next page.


Additional context

Below is the code for the example in the video. In my code I vary the height of a Container but this will work with anything that affects widget height, e.g. Visibility, etc, and still occurs even if you add smooth animations between heights. It will also work regardless of whether the second page has static or variable height.

/// The function that shows the multi-page modal
Future<void> showExampleModal(BuildContext context) {
  final currentPageNotifier = ValueNotifier(0);

  return WoltModalSheet.show(
    context: context,
    barrierDismissible: true,
    modalBarrierColor: Colors.black,
    useRootNavigator: true,
    pageIndexNotifier: currentPageNotifier,
    pageListBuilder: (BuildContext context) => [
      WoltModalSheetPage(
        child: VariableHeightWidget(
          goToOtherPage: () => currentPageNotifier.value = 1,
        ),
      ),
      WoltModalSheetPage(
        child: StaticHeightWidget(
            goToOtherPage: () => currentPageNotifier.value = 0),
      ),
    ],
  );
}

/// The first page of the modal (height depends on state)
class VariableHeightWidget extends StatefulWidget {
  const VariableHeightWidget({super.key, required this.goToOtherPage});

  final void Function() goToOtherPage;

  @override
  State<VariableHeightWidget> createState() => _VariableHeightWidgetState();
}

class _VariableHeightWidgetState extends State<VariableHeightWidget> {
  bool isBigBox = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        GestureDetector(
          onTap: () => setState(() {
            isBigBox = !isBigBox;
          }),
          child: const Text('change height'),
        ),
        const SizedBox(height: 32),
        GestureDetector(
          onTap: widget.goToOtherPage,
          child: const Text('go to other page'),
        ),
        const SizedBox(height: 32),
        AnimatedContainer(
          duration: CustomDurations.slow500,
          height: isBigBox ? 400 : 100,
          color: Colors.red,
        ),
      ],
    );
  }
}

/// The second page of the modal (static height)
class StaticHeightWidget extends StatelessWidget {
  const StaticHeightWidget({
    super.key,
    required this.goToOtherPage,
  });

  final void Function() goToOtherPage;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        GestureDetector(
          onTap: goToOtherPage,
          child: const Text('go to other page'),
        ),
        const SizedBox(height: 32),
        Container(
          height: 200,
          color: Colors.blue,
        ),
      ],
    );
  }
}

@auradigitaldev auradigitaldev added bug Something isn't working in triage labels Apr 19, 2024
@ulusoyca
Copy link
Collaborator

This is indeed a bug and needs investigation
image

@ibraheemalayan
Copy link

We’re experiencing the same issue and its disturbing.

Are there any updates ?

@ibraheemalayan
Copy link

@ulusoyca
Our use case details, might help identify the issue

We have a future builder that loads a list of items ( or illustration if empty ). Initially, it shows a loading indicator that has a certain fixed height. Switching to another page in the modal sheet works fine while it's loading (still on the initial size).

However, once the data loads and the height changes, switching pages causes a sudden change to the maximum height before switching to the next page.

Placing AnimatedSize widgets didn’t help.
Here’s a video with slow animation and children wrapped in AnimatedSize widgets.

WhatsApp.Video.2024-09-27.at.08.50.09.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working in triage
Projects
None yet
Development

No branches or pull requests

3 participants