I'm new to Flutter,
I want to destruct cards created initially and construct them again as per data provided in API call.
Basically when I tap on button in UI, it should call APIs and based on data from API call, if it is different from the data I already have, I want to destruct cards and construct them again. How I can achieve this?


Solution 1: Shady Aziza

The cards will auto update their content when you make the call again, it is like refreshing your data.

I have made a simple example with a single card that shows data from this JSON Where I am calling the API first time in initState and then repeating the call each time I press on the FAB.

I am adding the index variable just to show you the updates (updating my single card with the next item in the list)

Also it is worth noting that I am handling the null or empty values poorly for the sake of time.

Also forget about the UI overflow ¯_(ツ)_/¯

enter image description here

class CardListExample extends StatefulWidget {
  @override
  _CardListExampleState createState() => new _CardListExampleState();
}

class _CardListExampleState extends State<CardListExample> {
  Map cardList = {};
  int index = 0;

  @override
  void initState() {
    _getRequests();
    super.initState();
  }

  _getRequests() async {
    String url = "https://jsonplaceholder.typicode.com/users";
    var httpClinet = createHttpClient();
    var response = await httpClinet.get(
      url,
    );
    var data = JSON.decode(response.body);
    //print (data);
    setState(() {
      this.cardList = data[index];
      this.index++;
    });
    print(cardList);
    print(cardList["name"]);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      floatingActionButton:
          new FloatingActionButton(onPressed: () => _getRequests()),
      appBar: new AppBar(
        title: new Text("Card List Example"),
      ),
      body: this.cardList != {}
          ? new ListView(children: <Widget>[
              new Card(
                child: new Column(
                  children: <Widget>[
                    new Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        new Text(
                          cardList["name"] ?? '',
                          style: Theme.of(context).textTheme.display1,
                        ),
                        new Text(
                          this.cardList['email'] ?? '',
                          maxLines: 50,
                        ),
                      ],
                    ),
                    new Text(cardList["website"] ?? '')
                  ],
                ),
              ),
            ])
          : new Center(child: new CircularProgressIndicator()),
    );
  }
}


Solution 2: Nirav Madariya

Yes, Answer from Aziza works.
Though I used the code as below :

void main() =>
  runApp(new MaterialApp(
      onGenerateRoute: (RouteSettings settings) {
        switch (settings.name) {
          case '/about':
            return new FromRightToLeft(
              builder: (_) => new _aboutPage.About(),
              settings: settings,
            );
        }
      },
    home : new HomePage(),
    theme: new ThemeData(
        fontFamily: 'Poppins',
        primarySwatch: Colors.blue,
    ),
  ));

class HomePage extends StatefulWidget{
  @override
  HomePageState createState() => new HomePageState();
}

class HomePageState extends State<HomePage>{
  List data;
  Future<String> getData() async{
    var response = await http.get(
        Uri.encodeFull(<SOMEURL>),
        headers: {
          "Accept" : "application/json"
        }
    );

    this.setState((){
      data = JSON.decode(response.body);
    });
    return "Success";
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this.getData();
  }

  @override
  Widget build(BuildContext context){
    return new Scaffold(
      appBar : new AppBar(
        title : new Text("ABC API"),
          actions: <Widget>[
            new IconButton( // action button
            icon: new Icon(Icons.cached),
            onPressed: () => getData(),
          )],
      ),
      drawer: new Drawer(
          child: new ListView(
            children: <Widget> [

              new Container(
                height: 120.0,
                child: new DrawerHeader(
                  padding: new EdgeInsets.all(0.0),
                  decoration: new BoxDecoration(
                    color: new Color(0xFFECEFF1),
                  ),
                  child: new Center(
                    child: new FlutterLogo(
                      colors: Colors.blueGrey,
                      size: 54.0,
                    ),
                  ),
                ),
              ),
              new ListTile(
                  leading: new Icon(Icons.chat),
                  title: new Text('Support'),
                  onTap: () {
                    Navigator.pop(context);
                    Navigator.of(context).pushNamed('/support');
                  }
              ),
              new ListTile(
                  leading: new Icon(Icons.info),
                  title: new Text('About'),
                  onTap: () {
                    Navigator.pop(context);
                    Navigator.of(context).pushNamed('/about');
                  }
              ),
              new Divider(),
              new ListTile(
                  leading: new Icon(Icons.exit_to_app),
                  title: new Text('Sign Out'),
                  onTap: () {
                    Navigator.pop(context);
                  }
              ),
            ],
          )
      ),
      body: this.data != null ?

      new ListView.builder(
        itemCount: data.length,
        itemBuilder: (BuildContext context, int index){
          return new Container(
            padding: new EdgeInsets.fromLTRB(8.0,5.0,8.0,0.0),
            child: new Card(
              child: new Padding(
                padding: new EdgeInsets.fromLTRB(10.0,12.0,8.0,0.0),
                child: new Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    new ListTile(
                      enabled: data[index]['active'] == '1' ? true : false,
                      title: new Text(data[index]['header'],
                        style:Theme.of(context).textTheme.headline,
                      ),
                      subtitle: new Text("\n" + data[index]['description']),
                    ),
                    new ButtonTheme.bar(
                      child: new ButtonBar(
                        children: <Widget>[
                          new FlatButton(
                            child: new Text(data[index]['action1']),
                            onPressed: data[index]['active'] == '1' ? _launchURL :null,
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        },
      )
      :new Center(child: new CircularProgressIndicator()),
    );
  }
}

_launchURL() async {
  const url = 'http://archive.org';
  if (await canLaunch(url)) {
    await launch(url);
  } else {
    throw 'Could not launch $url';
  }
}

class FromRightToLeft<T> extends MaterialPageRoute<T> {
  FromRightToLeft({ WidgetBuilder builder, RouteSettings settings })
      : super(builder: builder, settings: settings);

  @override
  Widget buildTransitions(
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
      Widget child) {

    if (settings.isInitialRoute)
      return child;

    return new SlideTransition(
      child: new Container(
        decoration: new BoxDecoration(
            boxShadow: [
              new BoxShadow(
                color: Colors.black26,
                blurRadius: 25.0,
              )
            ]
        ),
        child: child,
      ),
      position: new Tween(
        begin: const Offset(1.0, 0.0),
        end: const Offset(0.0, 0.0),
      )
          .animate(
          new CurvedAnimation(
            parent: animation,
            curve: Curves.fastOutSlowIn,
          )
      ),
    );
  }
  @override Duration get transitionDuration => const Duration(milliseconds: 400);
}

The above code includes Navigation drawer, page navigation animation and also answer to the above question.