动态地在Flutter中构造和构造卡片

时间:2018-04-08 17:53:32

标签: dart flutter

我是Flutter的新人,
我想破坏最初创建的卡,并根据API调用中提供的数据再次构建它们 基本上当我点击UI中的按钮时,它应该调用API并基于来自API调用的数据,如果它与我已有的数据不同,我想要破坏卡并再次构建它们。 我怎么能做到这一点?

2 个答案:

答案 0 :(得分:1)

当您再次拨打电话时,这些卡会自动更新其内容,就像刷新您的数据一样。

我做了一个简单的示例,其中一张卡片显示来自this JSON的数据我在initState第一次调用API,然后每次按下FAB时重复调用。< / p>

我正在添加索引变量只是为了向您显示更新(使用列表中的下一项更新我的单张卡)

另外值得注意的是,我为了时间而处理空值或空值。

还要忘记UI溢出¯_(ツ)_ /¯

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()),
    );
  }
}

答案 1 :(得分:1)

是的,来自Aziza的回答 虽然我使用了以下代码:

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);
}

以上代码包括导航抽屉,页面导航动画以及上述问题的答案。