将单个API响应转换为地图列表,以转换为颤动卡

将单个API响应转换为地图列表,以转换为颤动卡

问题描述:

为了将单个Map转换为卡片,我使用了flutter的食谱来创建Future.但是,我想使用地图"列表来完成此操作.我知道我需要创建一个列表,然后使用futurebuilder返回一个列表视图,但是我不确定如何添加到apitest()方法中以将每个Map添加到列表中然后进行转换.非常感谢您的帮助.

I have used the flutter cookbook to create a Future in order to convert a single Map into a card. However I want to do this with a list of Maps. I know I need to create a list and then use the futurebuilder to return a list view, but I am unsure how to add to the apitest() method to add each Map to a list to then convert. Any help is much appreciated.

这是main.dart:

This is main.dart:

import 'package:flutter/material.dart';

import './viewviews.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'API TEST',
      theme: new ThemeData(
        primarySwatch: Colors.purple,
        backgroundColor: Colors.black,
      ),
      home: CardPage(),
    );
  }
}

这是我用来构造对象的类:

This is my class to construct the object:

import 'package:flutter/material.dart';

class Post {
  final String appName;
  final String brandName;
  final int views;

  Post(
      {@required this.appName, @required this.brandName, @required this.views});

  factory Post.fromJson(Map<String, dynamic> json) {
    return (Post(
        views: json['Views'],
        brandName: json['brandname'],
        appName: json['appname']));
  }
}

最后是我用来进行api调用并使用futurebuilder的代码:

and finally the code I am using to make the api call and use the futurebuilder:

import 'dart:async';

//final List<Post> cardslist = [];

class CardPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
        appBar: AppBar(title: Text('API TEST')),
        body: ListView.builder(
          itemBuilder: cardbuilder,
          itemCount: 1,
        ));
  }
}

Future<Post> testapi() async {
  final apiresponse =
      await http.get('https://myriadapp-55adf.firebaseio.com/Views.json');
  print(apiresponse.body);
  return Post.fromJson(json.decode(apiresponse.body));
}

Widget cardbuilder(BuildContext context, int index) {
  return Container(
      margin: EdgeInsets.all(20.0),
      child: FutureBuilder<Post>(
          future: testapi(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Text(snapshot.data.appName);
            } else if (snapshot.hasError) {
              return Text(snapshot.hasError.toString());
            }
            return Center(child: CircularProgressIndicator());
          }));
}

我已注释掉创建列表的代码,但我知道我将需要此代码,我只需要解码json以向其添加Maps列表,然后使用Futurebuilder返回listview.谢谢.

I have commented out the code to create the list but I know I will need this, I just need to decode the json to add a list of Maps to it and then use Futurebuilder to return the listview. Thank you.

您的json实际上并未返回json数组,而是实际上返回了具有任意键名(如View1)的映射,因此我们将迭代该映射.您需要将FutureBuilder提升到可以一次处理整个json的地步,因此可以在页面级别进行.所以CardPage变成

Your json doesn't actually return a json array, it actually returns a map with arbitrary key names like View1, so we'll iterate that map. You need to hoist your FutureBuilder up to the point where you can deal with the whole json at once, so at the page level. So CardPage becomes

class CardPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('API TEST')),
      body: FutureBuilder<Map>(
        future: fetchData(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final Map<String, dynamic> data = snapshot.data;
            final List<Container> cards = data.keys
                .map((String s) => makeCard(Post.fromJson(data[s])))
                .toList();
            return ListView(
              children: cards,
            );
          } else if (snapshot.hasError) {
            return Text(snapshot.hasError.toString());
          }
          return const Center(
            child: CircularProgressIndicator(),
          );
        },
      ),
    );
  }

  Container makeCard(Post post) {
    return Container(
      margin: EdgeInsets.all(20.0),
      child: Text(post.appName),
    );
  }

  Future<Map> fetchData() async {
    final apiresponse =
        await http.get('https://myriadapp-55adf.firebaseio.com/Views.json');
    print(apiresponse.body);
    return json.decode(apiresponse.body);
  }
}