Skip to content

ExpansionTile can't be programmatically opened or closed #7024

Closed

Description

@jtrunick

Need a way to close (or open) TwoLevelListItem programmatically

Activity

  1. eseidelGoogle commented on Nov 28, 2016

    @eseidelGoogle
    Contributor

    Thanks for the bug. Note there is some work soon to be done on TwoLevelListItem in #4765 and #4430.

  2. HansMuller commented on Nov 28, 2016

    @HansMuller
    Contributor

    Sounds like a useful feature.

    Presently TwoLevelSublists aren't expanded initially. We should provide a way to specify the initial value for isExpanded and a TwoLevelListState method for expanding or collapsing the sublist.

    This approach implies that programmatically expanding/collapsing sublists is not the common case. Doing so will require adding a GlobalKey to the sublist so that you can refer to its state later.

    Sound OK?

  3. jtrunick commented on Dec 5, 2016

    @jtrunick
    Author

    I imagine it would not be the "usual case" as well. Sounds reasonable to me.

  4. added this to the milestone on Feb 27, 2017
  5. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    p: material_uimaterial_ui package in flutter/packages
    on Apr 24, 2018
  6. changed the title [-]TwoLevelListItem - programmatic close function[/-] [+]ExpansionTile can't be programmatically opened or closed[/+] on Apr 24, 2018
  7. modified the milestones: , on Apr 24, 2018
  8. boominadhaprakash commented on Sep 23, 2019

    @boominadhaprakash

    Hi @zoechi

    I am very much eager to know about any updates on this issue?

  9. dipendra-sharma commented on Nov 6, 2019

    @dipendra-sharma

    Use Random Key for a workaround. key: PageStorageKey("${DateTime.now().millisecondsSinceEpoch}"),

  10. Alekcei commented on Nov 25, 2019

    @Alekcei

    need public state or animate controller

  11. modified the milestones: , on Jan 7, 2020
  12. aydin-faruk commented on Jan 24, 2020

    @aydin-faruk

    This great solution

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'ExpansionTile Collapse',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'ExpansionTile Collapse'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
      // selected's value = 0. For default first item is open.
      int selected = 0; //attention
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            centerTitle: true,title: Text('ExpansionTile Collapse', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
          ),
          body: Container(color: Colors.white,
              child: SingleChildScrollView(
                  child : Column( 
                    children : [                  
                      ListView.builder(
    
                          key: Key('builder ${selected.toString()}'), //attention
    
                          padding: EdgeInsets.only(left: 13.0, right: 13.0, bottom: 25.0),
                          shrinkWrap: true,
                          physics: NeverScrollableScrollPhysics(),
                          itemCount: 5,
                          itemBuilder: (context, index) {                        
                            return Column(
                              children: <Widget>[
                                Divider(
                                  height: 17.0,
                                  color: Colors.white,
                                ), 
                                      ExpansionTile(  
    
                                            key: Key(index.toString()), //attention                                                                  
                                            initiallyExpanded : index==selected, //attention
    
                                            leading: Icon(Icons.person, size: 50.0, color: Colors.black,),
                                            title: Text('Faruk AYDIN ${index}',style: TextStyle(color: Color(0xFF09216B), fontSize: 17.0, fontWeight: FontWeight.bold)), 
                                            subtitle: Text('Software Engineer', style: TextStyle(color: Colors.black, fontSize: 13.0, fontWeight: FontWeight.bold),),
                                            children: <Widget>[                                       
                                              Padding(padding: EdgeInsets.all(25.0), 
                                                          child : Text('DETAİL ${index} \n' + 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using "Content here, content here", making it look like readable English.',)
                                                          ) 
                                            ],
                                            onExpansionChanged: ((newState){
                                                if(newState)
                                                    setState(() {
                                                      Duration(seconds:  20000);
                                                      selected = index; 
                                                    });
                                                    else setState(() {
                                                      selected = -1; 
                                                    });        
                                            })
                                          ),
                                     
                                  ]
                                );
                          },
                            )
                    ]
                        ),
              )           
            )
        );
      }
    }
    
    
  13. deshario commented on Jan 28, 2020

    @deshario

    @aydin-faruk How to add space before every sublist depend on its depper level in default example

  14. aydin-faruk commented on Feb 19, 2020

    @aydin-faruk

    @ aydin-faruk Her alt listeden önce nasıl boşluk eklenir varsayılan örnekte derinlik düzeyine bağlıdır

    you can Use

    Container(
    width: 200.0,
    height : 200,) 
    

    or

    Padding( padding:  EdgeInsets.only(
                                           left: 69.0,
                                           top: 15.0,
                                             bottom: 15.0,
                                            right: 30.0  ),
                                 child:  .. ) 
    

    or

    SizedBox(
      width: 200.0,
      height: 300.0,)
    
  15. deshario commented on Mar 3, 2020

    @deshario
  16. aydin-faruk commented on Mar 3, 2020

    @aydin-faruk

    I can't run to your code. Can you share your Entry Model?

  17. deshario commented on Mar 17, 2020

    @deshario

    @aydin-faruk

    class Entry {
    
      String title,key,hub;
      int amount;
      List<Entry>children;
    
      Entry(
        this.title,
        this.key,
        this.amount,
        [this.children = const <Entry>[]]
      );
    
      String getTitle() => this.title;
      void setTitle(title) => this.title = title;
    
      String getKey() => this.key;
      void setKey(key) => this.key = key;
    
      int getAmount() => this.amount;
      void setAmount(amount) => this.amount = amount;
    
      List<Entry> getChildren() => this.children;
    
    }
    
  18. aydin-faruk commented on Mar 17, 2020

    @aydin-faruk

    class Entry wants "Listchildren"
    This is vicious circle. What do you think ?

  19. deshario commented on Mar 25, 2020

    @deshario

    @aydin-faruk I'm not sure maybe ... If u have better solution i'm ready to change my code

  20. bero93 commented on Apr 8, 2020

    @bero93

    @aydin-faruk why there is Duration(seconds:20000) in your code?

    This great solution

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'ExpansionTile Collapse',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'ExpansionTile Collapse'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
      // selected's value = 0. For default first item is open.
      int selected = 0; //attention
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            centerTitle: true,title: Text('ExpansionTile Collapse', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
          ),
          body: Container(color: Colors.white,
              child: SingleChildScrollView(
                  child : Column( 
                    children : [                  
                      ListView.builder(
    
                          key: Key('builder ${selected.toString()}'), //attention
    
                          padding: EdgeInsets.only(left: 13.0, right: 13.0, bottom: 25.0),
                          shrinkWrap: true,
                          physics: NeverScrollableScrollPhysics(),
                          itemCount: 5,
                          itemBuilder: (context, index) {                        
                            return Column(
                              children: <Widget>[
                                Divider(
                                  height: 17.0,
                                  color: Colors.white,
                                ), 
                                      ExpansionTile(  
    
                                            key: Key(index.toString()), //attention                                                                  
                                            initiallyExpanded : index==selected, //attention
    
                                            leading: Icon(Icons.person, size: 50.0, color: Colors.black,),
                                            title: Text('Faruk AYDIN ${index}',style: TextStyle(color: Color(0xFF09216B), fontSize: 17.0, fontWeight: FontWeight.bold)), 
                                            subtitle: Text('Software Engineer', style: TextStyle(color: Colors.black, fontSize: 13.0, fontWeight: FontWeight.bold),),
                                            children: <Widget>[                                       
                                              Padding(padding: EdgeInsets.all(25.0), 
                                                          child : Text('DETAİL ${index} \n' + 'It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using "Content here, content here", making it look like readable English.',)
                                                          ) 
                                            ],
                                            onExpansionChanged: ((newState){
                                                if(newState)
                                                    setState(() {
                                                      Duration(seconds:  20000);
                                                      selected = index; 
                                                    });
                                                    else setState(() {
                                                      selected = -1; 
                                                    });        
                                            })
                                          ),
                                     
                                  ]
                                );
                          },
                            )
                    ]
                        ),
              )           
            )
        );
      }
    }
    
  21. 2ZeroSix commented on May 2, 2020

    @2ZeroSix
    Contributor

    @HansMuller it doesn't fixed yet.
    initiallyExpanded applies only for initial state, so the key of the widget should be changed to apply changes, and then animation won't work

  22. lock commented on May 21, 2020

    @lock

    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.

  23. locked and limited conversation to collaborators on May 21, 2020
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

    c: new featureNothing broken; request for a new capabilityframeworkflutter/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