Flutter FutureBuilder 在另一个 FutureBuilder 中,取自 JSON 字符串数组

Posted

技术标签:

【中文标题】Flutter FutureBuilder 在另一个 FutureBuilder 中,取自 JSON 字符串数组【英文标题】:Flutter FutureBuilder inside another FutureBuilder, Taken From JSON array of Strings 【发布时间】:2019-09-12 23:52:22 【问题描述】:

我想在另一个 Futurebuilder 中添加一个 Futurebuilder。我有一个JSON,我想在CircleAvatars 中显示用户名,只有第一个字母可见!

我已经尝试了很多改变班级和他们的阵型,试图让它发挥作用,但我似乎永远无法完成这项工作!

我收到以下错误:

flutter:抛出了另一个异常:NoSuchMethodError: The getter 'length' 在 null 上调用。

flutter:抛出另一个异常:NoSuchMethodError:方法 '[]' 在 null 上被调用。

JSON:



"id": 81,
"users": [
    
        "username": "hugo",
        "fullname": "Hugo Johnsson"
    ,
    
        "username": "studentone",
        "fullname": "Student One"
    
],
"title": "test med teacher chat",
"description": "This project does not have a description.",
"subject": "No subject",
"deadline": "2019-01-06",
"days_left": "107 days ago",
"overview_requests": [
    
        "id": 28,
        "user": 
            "username": "hugo",
            "fullname": "Hugo Johnsson"
        ,
        "group": 81
    
]


Flutter 中的类:

class Project 
  final int id;
  final String title;
  final String description;
  final String deadline;
  final String subject;
  final String days_left;
  final List<USER> users;

  Project(
      this.id,
      this.title,
      this.description,
      this.deadline,
      this.subject,
      this.days_left,
      this.users
  );


class USER 
  final String username;
  final String fullname;

USER(
  this.username,
  this.fullname
  );

未来:

  Future<List<Project>> _getProjects() async 
var data = await http.get(
    "http://studieplaneraren.pythonanywhere.com/api/projects/$UserLog().Username/?format=json");
var jsonData = json.decode(data.body); //an array of json objects

List<Project> allProjects = [];

for (var JData in jsonData) 
  Project project = Project(
      JData["id"],
      JData["title"],
      JData["description"],
      JData["deadline"],
      JData["subject"],
      JData["days_left"],
      JData[USER("username", "fullname")]
  );

  allProjects.add(project);


return allProjects;

CircleAvatars:

                      //CIRCLE AVATARS
                  Container(
                    margin: EdgeInsets.only(top: 10, left: 8, right: 8),
                    height: 40,
                    child: FutureBuilder(
                      future: _getProjects(),
                      builder: (context, snapshot) => ListView.builder(
                        itemCount: snapshot.data.length,
                        itemBuilder: (context, userIndex) =>
                            CircleAvatar(
                              foregroundColor: Colors.white,
                              backgroundColor: UserLog().Color,
                              child: Text(snapshot.data[index].users[userIndex].username[0]),
                            )
                      )
                    )
                    ),

【问题讨论】:

【参考方案1】:

你可以试试下面的代码。

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

class FutureBuilderJSON extends StatefulWidget 
  FutureBuilderJSON(Key key) : super(key: key);

  _FutureBuilderJSONState createState() => _FutureBuilderJSONState();


class _FutureBuilderJSONState extends State<FutureBuilderJSON> 
  Future<List<Project>> _getProjects() async 
    var data = await http.get(
        "http://studieplaneraren.pythonanywhere.com/api/projects/hugo/?format=json");
    var jsonData = json.decode(data.body); //an array of json objects
    List<Project> allProjects = [];
    for (var JData in jsonData) 
      Project project = Project(
        JData["id"],
        JData["title"],
        JData["description"],
        JData["deadline"],
        JData["subject"],
        JData["days_left"],
        JData["users"],
      );
      allProjects.add(project);
    

    return allProjects;
  

  @override
  Widget build(BuildContext context) 
    return Container(
      margin: EdgeInsets.only(top: 10, left: 8, right: 8),
      child: FutureBuilder<List<Project>>(
        future: _getProjects(),
        builder: (context, snapshot) 
          if (!snapshot.hasData)
            return Center(child: CircularProgressIndicator());
          return ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (context, index) 
              List<dynamic> users = snapshot.data[index].users;
              List<Widget> ws = List<Widget>();
              users.forEach((u) 
                var oneChar = u['username'].substring(0, 1).toUpperCase();
                var w = CircleAvatar(
                  foregroundColor: Colors.white,
                  backgroundColor: Colors.blue,
                  child: Text(oneChar),
                );
                ws.add(w);
              );
              // String username =
              //     users != null ? users[0]['username'] : 'Default';
              // var oneChar = username.substring(0, 1).toUpperCase();

              // return CircleAvatar(
              //   foregroundColor: Colors.white,
              //   backgroundColor: Colors.blue,
              //   child: Text(oneChar),
              // );
              return Column(
                children: ws,
              );
            ,
          );
        ,
      ),
    );
  


class Project 
  final int id;
  final String title;
  final String description;
  final String deadline;
  final String subject;
  final String days_left;
  final List<dynamic> users;

  Project(
    this.id,
    this.title,
    this.description,
    this.deadline,
    this.subject,
    this.days_left,
    this.users,
  );


class User 
  final String username;
  final String fullname;
  User(this.username, this.fullname);

【讨论】:

我仍然在每个单元格中得到 H, 查看此屏幕截图imgur.com/a/IzzOeWY 并查看完整源代码github.com/santoshanand/***-flutter【参考方案2】:

试试这个

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

class FutureBuilderJSON extends StatefulWidget 
  FutureBuilderJSON(Key key) : super(key: key);

  _FutureBuilderJSONState createState() => _FutureBuilderJSONState();


class _FutureBuilderJSONState extends State<FutureBuilderJSON> 
  Future<List<Project>> _getProjects() async 
    var data = await http.get(
        "http://studieplaneraren.pythonanywhere.com/api/projects/hugo/?format=json");
    var jsonData = json.decode(data.body); //an array of json objects
    List<Project> allProjects = [];
    for (var JData in jsonData) 
      Project project = Project(
        JData["id"],
        JData["title"],
        JData["description"],
        JData["deadline"],
        JData["subject"],
        JData["days_left"],
        JData["users"],
      );
      allProjects.add(project);
    

    return allProjects;
  

  @override
  Widget build(BuildContext context) 
    return Container(
      margin: EdgeInsets.only(top: 10, left: 8, right: 8),
      child: FutureBuilder<List<Project>>(
        future: _getProjects(),
        builder: (context, snapshot) 
          if (!snapshot.hasData)
            return Center(child: CircularProgressIndicator());
          return ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (context, index) 
              var users = snapshot.data[index].users;
              String username =
                  users != null ? users[0]['username'] : 'Default';
              var oneChar = username.substring(0, 1).toUpperCase();
              return CircleAvatar(
                foregroundColor: Colors.white,
                backgroundColor: Colors.blue,
                child: Text(oneChar),
              );
            ,
          );
        ,
      ),
    );
  


class Project 
  final int id;
  final String title;
  final String description;
  final String deadline;
  final String subject;
  final String days_left;
  final List<dynamic> users;

  Project(
    this.id,
    this.title,
    this.description,
    this.deadline,
    this.subject,
    this.days_left,
    this.users,
  );


class User 
  final String username;
  final String fullname;
  User(this.username, this.fullname);

【讨论】:

非常感谢 :) 只是一个问题 - 我在所有单元格中都得到了字母 H,而不是 H...S... 是的,因为 json 响应在所有记录中都返回“hugo” 你想展示什么?我正在选择用户名,然后取用户名属性的第一个字符 我要返回用户 H 和 S

以上是关于Flutter FutureBuilder 在另一个 FutureBuilder 中,取自 JSON 字符串数组的主要内容,如果未能解决你的问题,请参考以下文章

Flutter + SharedPreferences:如何使用 FutureBuilder

Flutter StreamBuilder 与 FutureBuilder

Flutter:FutureBuilder 中的异步调用

Flutter HiveDB 在 FutureBuilder 上使用框

Flutter Widgets 之 FutureBuilder

Flutter Futurebuilder 快照为空