Skip to content

Animations package hides widget, but widget is still accessible #51300

Closed
flutter/packages
#135

Description

@bergamin

I'm trying to use Fade for hiding or showing a FAB button with an animation, but after it is hidden it is still accessible.

It is possible to notice this in the Fade example. Add an action to the onPressed of the example FAB and tap HIDE FAB button. Then, tap the region where the FAB was. The action will still happen.

Activity

  1. added
    packageflutter/packages repository. See also p: labels.
    on Feb 24, 2020
  2. dnfield commented on Feb 24, 2020

    @dnfield
    Contributor

    The FadeScaleTransition should probably make it clearer that you probably want to drop the widget from the tree when it fades to 0.

    In general, I think we should at the least add an assertion around hit testing for widgets like this where they check if the opacity is 0, and if so assert with a suggestion that you're using the wrong kind of widget to do hit testing without drawing anything. See #51000 (comment)

    /cc @goderbauer @shihaohong

  3. dnfield commented on Feb 24, 2020

    @dnfield
    Contributor

    You should be able to work around this today, btw, by just dropping the widget yourself in cases where the animation controller's value has hit zero.

  4. bergamin commented on Feb 24, 2020

    @bergamin
    Author

    I'm new to flutter. Before finding the animations package, I was hiding my fab using Visibility widget. Is it possible to set the visibility based on that? Like, checking the alpha for deciding the visibility or something in these lines. This would make the Visibility widget trigger at the right moment in the animation.

  5. dnfield commented on Feb 24, 2020

    @dnfield
    Contributor

    Yeah, something like this should work:

          floatingActionButton: AnimatedBuilder(
            animation: _controller,
            builder: (BuildContext context, Widget child) {
              return FadeScaleTransition(
                animation: _controller,
                child: child,
              );
            },
            child: Visibility(
              visible: _controller.value > 0.0,
              child: FloatingActionButton(
                child: Icon(Icons.add),
                onPressed: () {},
              ),
            ),
          ),
  6. goderbauer commented on Feb 24, 2020

    @goderbauer
    Member

    We should update the examples in the example app to actually do this correctly.

  7. shihaohong commented on Feb 24, 2020

    @shihaohong
    Contributor

    I can fix the example app! I'll probably create a separate issue to improve the sample docs with:

    • Short code samples (if possible, for cases like the one above)
    • Links to the Material motion system article that is now published
  8. self-assigned this
    on Feb 24, 2020
  9. bergamin commented on Feb 24, 2020

    @bergamin
    Author

    @dnfield thanks! That's what I was thinking about. I'll try that.

  10. bergamin commented on Feb 24, 2020

    @bergamin
    Author

    It seems Visibility alone won't be able to solve this. It looks like it is testing the controller's value for visibility before the animation even starts, which makes it flash into existence and disappear through the animation but still accessible, or invisible when it should be shown.

    Inverting the test to == 0 will show and hide when intended, but the hiding animation is hidden by visibility being triggered before we actually need it to. It will have the same behaviour of using _showFab here.

    Looking at the Visibility documentation, I found IgnorePointer, which is what I'm going to use for now. It works pretty well:

          floatingActionButton: AnimatedBuilder(
            animation: _controller,
            builder: (BuildContext context, Widget child) {
              return FadeScaleTransition(
                animation: _controller,
                child: child,
              );
            },
            child: IgnorePointer(
              ignoring: !_showFab,
              child: FloatingActionButton(
                child: Icon(Icons.add),
                onPressed: () { },
              ),
            ),
          ),
  11. dnfield commented on Feb 24, 2020

    @dnfield
    Contributor

    What about if you still use the Visibility widget, but set visible to _showFab?

    The problem with using just IgnorePointer is that it will still build the child widget, which may be non-trivial. For a FAB it's probably not that big of a deal, but depending on what your actual widget is it could make a big difference, particularly if your actual widget animates/pumps frames on every tick.

  12. bergamin commented on Feb 24, 2020

    @bergamin
    Author

    Yes, not ideal, but it's going to be it for now.

    If I use _showFab in Visibility, it does work, but the hiding animation isn't shown because Visibility is hiding the FAB before the animation starts.

  13. dnfield commented on Feb 24, 2020

    @dnfield
    Contributor

    Ahh ok, there should be some way to fix that but sounds good.

  14. shihaohong commented on Feb 25, 2020

    @shihaohong
    Contributor

    @bergamin Could you try using AnimationController.status == AnimationStatus.dismissed as well?

  15. bergamin commented on Feb 25, 2020

    @bergamin
    Author

    @shihaohong you mean in Visibility? It doesn't show the FAB.

    I put a Toast in the show/hide button to check what values are being read at that time (which I believe is the same time Visibility is being triggered) and it shows status as AnimationStatus.forward and AnimationStatus.reverse

    Edit: I put the toast after the actions already programmed in the button of the example

    If I put before, it shows AnimationStatus.dismissed and AnimationStatus.completed respectively

  16. bergamin commented on Feb 25, 2020

    @bergamin
    Author

    I tried the opposite, testing != dismissed and the animations are shown correctly, but the FAB is still accessible and on hitting it, the toast would show status as dismissed. I believe these status that require the animation to end before triggering Visibility won't work this way. Unless there is a way to delay Visibility or make it keep testing until we get to the desired animation stage

  17. github-actions commented on Aug 22, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  18. locked as resolved and limited conversation to collaborators on Aug 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

p: animationsThe animations packagepackageflutter/packages repository. See also p: labels.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions