【问题标题】:Convert Single API reponse to a list of Maps to convert to cards in flutter将单个 API 响应转换为地图列表以在颤动中转换为卡片
【发布时间】:2019-02-06 19:49:44
【问题描述】:

我已经使用颤振食谱创建了一个未来,以便将单个地图转换为一张卡片。但是我想用地图列表来做到这一点。我知道我需要创建一个列表,然后使用 futurebuilder 返回一个列表视图,但我不确定如何添加到 apitest() 方法以将每个 Map 添加到列表中然后进行转换。非常感谢任何帮助。

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

这是我构造对象的类:

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 的代码:

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 以向其中添加地图列表,然后使用 Futurebuilder 返回列表视图。谢谢。

【问题讨论】:

    标签: android dart flutter future


    【解决方案1】:

    您的 json 实际上并没有返回一个 json 数组,它实际上返回了一个带有任意键名的映射,例如 View1,因此我们将迭代该映射。您需要将 FutureBuilder 提升到可以一次处理整个 json 的程度,因此是在页面级别。所以CardPage变成了

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

    【讨论】:

    • 这很完美!非常感谢理查德。只有一个最终查询,因为未来的构建器只返回一个列表视图,重新运行一个 listview.builder 是否性能更高,或者未来构建器是否涵盖了性能方面?再次感谢。
    • 这真的取决于你的名单有多大。由于您的 API 响应包含整个列表,因此使用其“普通”构造函数制作整个 ListView 是最简单的。如果列表很大时性能受到影响,您可以只构建一个 Posts 列表而不是 Containers 并返回一个 ListView.builder,它将按需构建每个 Container。你会知道Post 列表的大小,.builder 构造函数可能需要它。
    • 谢谢,进行这些更改和其他一些更改,包括在主要功能之外初始化汽车列表,我现在使用listview.builder 来生成性能列表。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多