Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate child when using FutureBuilder

I have a FutureBuilder in my app with the conventional structure:

FutureBuilder(
  future: futureData(),
  builder: (context, snapshot) {
    if(snapshot.connectionState == waiting) {
      return Center(
        child: SpinKitCircle(color: Colors.blue),
      );
    } else {
      return ListView.builder();
    }
  }
)

I don't like when it just suddenly pops on the screen, so, my final question is, how can I make the ListView.builder() to get rendered by the FutureBuilder in an animated way?

like image 524
Bruno Dias Avatar asked Apr 24 '20 01:04

Bruno Dias


2 Answers

Use AnimatedSwitcher to fade out previous child and fade in new.

FutureBuilder(
  future: futureData(),
  builder: (context, snapshot) {
    Widget child;
    if (snapshot.connectionState == ConnectionState.waiting) {
      child = CircularProgressIndicator(
        key: ValueKey(0), // assign key
      );
    } else {
      child = ListView.builder(
        key: ValueKey(1), // assign key
      );
    }

    return AnimatedSwitcher(
      duration: Duration(seconds: 1),
      child: child,
    );
  },
);
like image 110
CopsOnRoad Avatar answered Sep 29 '22 08:09

CopsOnRoad


Using AnimatedSwitcher and storing the widget we wanna show in a variable child and updating it's value in evry case to avoid erros of missing a return use continue statement and jump to the return that has AnimatedSwitcher everytime in my case i called it display

FutureBuilder(

      future: http.get(
        "https://source.unsplash.com/random?portrait",
      ),
      // ignore: missing_return
      builder: (ctx, snapshot) {
        Widget child;
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.active:
          case ConnectionState.waiting:
            child = Container(
              width: width * 0.2,
              height: width * 0.2,
              child: Center(
                child: Container(
                  width: width * 0.1,
                  child: CircularProgressIndicator(),
                ),
              ),
            );
            continue display;
          case ConnectionState.done:
            if (snapshot.hasError) return CircleAvatar(child: Text('Error: '));
            // when we get the data from the http call, we give the bodyBytes to Image.memory for showing the image
            child = CircleAvatar(
                radius: width * 0.1,
                backgroundImage: MemoryImage(snapshot.data.bodyBytes));
            continue display;
          display:
          default:
            return AnimatedSwitcher(
              duration: Duration(milliseconds: 300),
              child: child,
            );
        }
      },
    );
like image 24
Mostefaoui Mohammed Amin Avatar answered Sep 29 '22 07:09

Mostefaoui Mohammed Amin