Skip to content

Programmatically open and close ExpansionTile Widget. #60387

Closed

Description

@ritvij-saxena

I was building a Card which would be placed at the bottom of the screen, ExpansionTile is the child of this widget. When I click this card, the showModalBottomSheet() is called in OnExpansionChanged, however, I don't know how to close it. An open and close feature would be nice.

code reference: https://gist.github.com/ritvij-saxena/4726b3a834b8aa4afb7305eda2c970da
Live demo: https://dartpad.dev/4726b3a834b8aa4afb7305eda2c970da

Activity

  1. TahaTesser commented on Jun 29, 2020

    @TahaTesser
    Contributor

    Related to #7024
    Currently we only have initiallyExpanded which does it initially and there is no way to close ExpansionTile afterwards programmatically #7024 (comment)

  2. added
    c: new featureNothing broken; request for a new capability
    and removed
    c: new featureNothing broken; request for a new capability
    on Jun 29, 2020
  3. added
    p: material_uimaterial_ui package in flutter/packages
    frameworkflutter/packages/flutter repository. See also f: labels.
    c: new featureNothing broken; request for a new capability
    on Jun 29, 2020
  4. ritvij-saxena commented on Jun 29, 2020

    @ritvij-saxena
    Author

    Should I be looking forward to this feature in the near future?

  5. maksof-Hussain commented on Aug 5, 2020

    @maksof-Hussain

    is there any way to close or open an ExpansionList in current version without loosing the animation?

  6. Nuytemans-Dieter commented on Aug 14, 2020

    @Nuytemans-Dieter

    For those looking for a solution before this has been implemented in Flutter:
    You can simply copy the code of ExpansionTile and make a few changes.

    • I suggest renaming ExpansionTile and _ExpansionTileState to something else so the names don't cause confusion.
    • Make the previous _ExpansionTileState public (because we'll need to use a GlobalKey)
    • Add the method below. This will toggle the animation and state of ExpansionTileState when the new setting is different from the current one and changes nothing otherwise.
      void setExpanded(bool doExpand)
      {
        if ( doExpand != _isExpanded)
          _handleTap();      
      }
    

    Now simply initialise ExpansionTile with a key and keep a reference to that key wherever you are using the Widget. Then you can call key.currentState.setExpanded(bool newExpandedState) when needed. Or click here to see my implementation. Edit: view code here, this version has an openExpansion and closeExpansion method instead of the setExpanded above so keep that in mind.

    The actual implementation in Flutter will probably differ though (as I don't believe they want to expose _ExpansionTileState).

  7. AtamyratBabayev commented on Aug 21, 2020

    @AtamyratBabayev

    For those looking for a solution before this has been implemented in Flutter:
    You can simply copy the code of ExpansionTile and make a few changes.

    • I suggest renaming ExpansionTile and _ExpansionTileState to something else so the names don't cause confusion.
    • Make the previous _ExpansionTileState public (because we'll need to use a GlobalKey)
    • Add the method below. This will toggle the animation and state of ExpansionTileState when the new setting is different from the current one and changes nothing otherwise.
      void setExpanded(bool doExpand)
      {
        if ( doExpand != _isExpanded)
          _handleTap();      
      }
    

    Now simply initialise ExpansionTile with a key and keep a reference to that key wherever you are using the Widget. Then you can call key.currentState.setExpanded(bool newExpandedState) when needed. Or click here to see my implementation.

    The actual implementation in Flutter will probably differ though (as I don't believe they want to expose _ExpansionTileState).

    Hello! Your link is broken.. Could you update it? Thanks)

  8. Nuytemans-Dieter commented on Aug 21, 2020

    @Nuytemans-Dieter

    For those looking for a solution before this has been implemented in Flutter:
    You can simply copy the code of ExpansionTile and make a few changes.

    • I suggest renaming ExpansionTile and _ExpansionTileState to something else so the names don't cause confusion.
    • Make the previous _ExpansionTileState public (because we'll need to use a GlobalKey)
    • Add the method below. This will toggle the animation and state of ExpansionTileState when the new setting is different from the current one and changes nothing otherwise.
      void setExpanded(bool doExpand)
      {
        if ( doExpand != _isExpanded)
          _handleTap();      
      }
    

    Now simply initialise ExpansionTile with a key and keep a reference to that key wherever you are using the Widget. Then you can call key.currentState.setExpanded(bool newExpandedState) when needed. Or click here to see my implementation.
    The actual implementation in Flutter will probably differ though (as I don't believe they want to expose _ExpansionTileState).

    Hello! Your link is broken.. Could you update it? Thanks)

    Woops, my bad. Fixed it.

  9. caseycrogers commented on May 3, 2021

    @caseycrogers
    Contributor

    FWIW, it's far far more elegant to use ExpansionPanel which supports programmatically expanding and collapsing rather than changing keys to force an ExpansionTile to be rebuilt (which breaks the expansion/collapse animations).

  10. mrtdeh commented on Sep 27, 2021

    @mrtdeh

    its easy with this trick :

    1- open expantion_tile.dart
    2- in the state class and add this code :

    
      @override
      void didUpdateWidget(ExpansionTile oldWidget) {
        super.didUpdateWidget(oldWidget);
        if (oldWidget.initiallyExpanded != widget.initiallyExpanded) {
          _handleTap();
        }
      }
    

    and then you can use initiallyExpanded property as your own isExapnded and change it...!!

    .
    .
    ExpansionTile(
            initiallyExpanded: _isExpanded,
    .
    .
    

    and next :`

    .
    .
    onPressed: () {
            print("hello");
            setState(() {
              _isExpanded = !_isExpanded;
            });
          },
    .
    .
    

    remember restart your app for apply changes...
    its worked for me.

  11. caseycrogers commented on Sep 28, 2021

    @caseycrogers
    Contributor

    its easy with this trick :

    .
    .
    .

    remember restart your app for apply changes... its worked for me.

    Editing code from external libraries (such as Flutter), is HIGHLY discouraged.

    When Flutter releases updates you're likely to get merge conflicts and/or the update will trample your local changes. Instead, you should make your changes a PR against flutter/flutter (of course adding tests and making sure your code is bug-free).

    Contributing to flutter has a little bit of a learning curve but it's really not bad. See the contributing guide.

  12. 4 remaining items

  13. ChiPhanTlm commented on Jun 10, 2022

    @ChiPhanTlm
    @override
      void didUpdateWidget(AppExpansionTile oldWidget) {
        if (oldWidget.isExpanded != widget.isExpanded &&
            (_controller.status != AnimationStatus.forward ||
                _controller.status != AnimationStatus.reverse)) {
          if (widget.isExpanded) {
            _controller.forward().then((value) {
              setState(() {
                _isExpanded = widget.isExpanded;
              });
            });
          } else {
            _controller.reverse().then((value) {
              setState(() {
                _isExpanded = widget.isExpanded;
              });
            });
          }
        }
        super.didUpdateWidget(oldWidget);
      }
    
    

    I custom the method base on other answers

  14. caseycrogers commented on Jun 10, 2022

    @caseycrogers
    Contributor

    I custom the method base on other answers

    Lol guys you all should really stop doing this. Updates will trample and break your changes-don't get in the habit of editing external libraries. It's extremally brittle.

    If you all promise to stop editing external libraries I'll make a PR against ExpansionTile to support programmatic control.

  15. glaceon2000 commented on Aug 30, 2022

    @glaceon2000

    It's been more than 2 years and nothing?

  16. Nuytemans-Dieter commented on Aug 30, 2022

    @Nuytemans-Dieter

    It's been more than 2 years and nothing?

    Some PRs have been made but all have been closed. This comment in #95727 suggests a good approach though.

  17. globaltop126 commented on Oct 26, 2022

    @globaltop126

    Hello @ritvij-saxena.
    Did you solve this problem?
    I got an issue like this.
    I want your contact.
    Thank you.

  18. added
    P1High-priority issues at the top of the work list
    and removed
    P1High-priority issues at the top of the work list
    on Mar 22, 2023
  19. github-actions commented on Apr 7, 2023

    @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.

  20. locked as resolved and limited conversation to collaborators on Apr 7, 2023
  21. added
    P0Critical issues such as a build break or regression
    and removed on Jun 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Critical issues such as a build break or regressionc: new featureNothing broken; request for a new capabilitycustomer: chalk (g3)frameworkflutter/packages/flutter repository. See also f: labels.p: material_uimaterial_ui package in flutter/packages

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions