skip to Main Content

I have the following code:

ExpansionTile(
  maintainState: true,
  children: [
    FutureBuilder(
      future: _future,
      builder: ...
    )
  ]
)

The default behavior is building all the widgets together. I would like to first build the ExpansionTile, and then, on ExpansionTile expanded, build the FutureBuilder calling _future.

2

Answers


  1. In my thinking the FutureBuilder is very dumb Widget as it rebuild it self on every state change.
    Still, i found a work around for your issue.

    you refer to the below code:

      dynamic futureFunction;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: ExpansionTile(
              title: const Text('Title'),
              childrenPadding: const EdgeInsets.all(16),
              onExpansionChanged: (value) {
                setState(() {
                  futureFunction = value ? _future() : null;
                });
              },
              children: [
                FutureBuilder<String>(
                  future: futureFunction,
                  builder: (context, snapshot) {
                    futureFunction = null;
                    // your operations and returning widget.
                    return Text(snapshot.data ?? 'Loading');
                  },
                )
              ],
            ),
          ),
        );
      }
    
      Future<String> _future() async {
        print('inside _future()');
        await Future.delayed(
          const Duration(seconds: 2),
        );
        return 'Working';
      }
    

    Here i have taken a dynamic variable ‘futureFun’ that will have null or the future function itself and given to the FutureBuilder future property(FutureBuilder don’t build itself if you pass null to the future property).

    Firstly, it will be null then if you expand the expansionTile it will be assigned with the future function, and after the performing your operations in the futureBuilder you can make it null so it doesn’t rebuild on every setState.

    Login or Signup to reply.
  2. You can, pseudo code that goes along with your code

    ExpansionTile(
      maintainState: true,
      children: [
        Builder(builder: (BuildContext context) {
            // check if your expansion tile is expanded
           // if expanded 
               return  FutureBuilder(
                         future: _future,
                         builder: ...
            );
          // if not expanded, return anything you want like empty 
              return SizedBox();
        },
      ]
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search