2

I have a parent widget which is a Container() and a child widget which is a FutureBuilder...

In my app I need to change the height of the container so that it fits the newly added items in the FutureBuilder But the problem is when I setState and change the parent widget's (Container()'s) height the FutureBuilder gets rebuilt again

Now, that's to be expected and is the normal behavior...

Now the question. How can I prevent my child's widget from rebuilding and rebuild only the parent widget?

Like a way to save the data into the RAM or something...

Also, I'm using AutomaticKeepAliveClientMixin but to no avail;

Here is my code

Parent


\\ Somewhere here I call setState and change the value of _latestPostsHeight

    Container(
       child: LatestPosts(),
       height: _latestPostsHeight,
     ),

And this my LatestPosts() which is a FutureBuilder


class _LatestPostsState extends State<LatestPosts>
    with AutomaticKeepAliveClientMixin {
  bool get wantKeepAlive => true;

  bool _isFirstTime = true;

  Future<List<Post>> _posts() async {
    final Future<List<Post>> _posts =
        context.read(fetchPostsProvider({'perPage': 5, 'pageNum': 1}).future);
    return _posts;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return FutureBuilder(
        future: _posts(),
        builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Column(
              children: [
                for (var i = 0; i < 7; i++) PostShimmer(),
              ],
            );
          } else if (snapshot.connectionState == ConnectionState.done) {
            if (_isFirstTime) {
              SchedulerBinding.instance
                  .addPostFrameCallback((_) => setState(() {
                        _isFirstTime = false;
                        final boolProvider =
                            context.read(latestPostsDataLoaded);
                        boolProvider.state = true;
                      }));
            }

            return Column(
              children: [
                for (var i = 0; i < snapshot.data.length; i++)
                  SimplePostContainer(
                      data: snapshot.data, index: i, type: SearchOrPost.post)
              ],
            );
          } else {
            return Container();
          }
        });
  }
}

What can I do?

1 Answers1

0
  bool futureCalled = false;

  Future post(){
    setState(() {
    futureCalled = true;
    });
  }
  
  Widget build(BuildContext context) {

    return Container(
      height:containerHeight ,
      child: FutureBuilder(
        future: futureCalled ? null : post(), //handle child redraw 
        builder: (BuildContext context, snapshot){
         .....
    );
  }

Hope this may help you, let me know if this works.

shorol
  • 790
  • 5
  • 11
  • In the future, please try to solve the problem with an explanation and not just send a big block of code. ;) – m123 Jan 12 '21 at 10:47
  • Sorry, but this doesn't work... Please, read the question carefully... And thanks for your help – Hussein Al-mosawi Jan 12 '21 at 11:55
  • I want to keep the data not lose it – Hussein Al-mosawi Jan 12 '21 at 11:55
  • **future: futureCalled ? null : post()**, here you won't lose data, **post()** will run only once when you first draw your widget, after that if you want to update your parent widget without redraw child, just set **futureCalled = true**, it will only draw your parent. Again to draw future child just set **futureCalled = false**, it will rebuild your child too. i think this is what you want, please let me know if i didn't get the question. – shorol Jan 12 '21 at 12:20
  • This does not work :) But the future builder keeps refiring – Hussein Al-Mosawi Jan 13 '21 at 11:51