【问题标题】:Take names from JSON array and display first character in Listview从 JSON 数组中获取名称并在 Listview 中显示第一个字符
【发布时间】:2019-09-14 04:42:48
【问题描述】:

我有一个项目列表视图,这些项目都有分配给他们的成员,我想用 Listview.builder 在 Futurebuilder 中显示这些成员,我想返回一个 CircleAvatar,其名称的第一个字母如下:'H ' - 'S' ...

我尝试过这样做,但我在所有单元格中都收到了字母“H”。我希望它是这样的:'H' 和 'S' - 代表 hugo 和 studentone!

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

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": "109 days ago",
    "overview_requests": [
        {
            "id": 28,
            "user": {
                "username": "hugo",
                "fullname": "Hugo Johnsson"
            },
            "group": 81
        }
    ]
},
{
    "id": 83,
    "users": [
        {
            "username": "hugo",
            "fullname": "Hugo Johnsson"
        }
    ],
    "title": "A ducking project",
    "description": "Hej nu har du din ändrade beskrivning!",
    "subject": "No subject",
    "deadline": "2019-01-09",
    "days_left": "106 days ago",
    "overview_requests": []
},
{
    "id": 86,
    "users": [
        {
            "username": "hugo",
            "fullname": "Hugo Johnsson"
        }
    ],
    "title": "tettestdsfsdf",
    "description": "sdfsadfasdfasdfsadf",
    "subject": "No subject",
    "deadline": "2019-01-09",
    "days_left": "106 days ago",
    "overview_requests": []
}
]

Here is a picture of the APP

Here is a screenshot of how It looks now! with the row implemented!

这是卡片/用户界面

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: _getProjects(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.data == null) {
             return Container(
              child: Center(
                child: CircularProgressIndicator(),
            ),
        );
      } else
        return ListView.builder(
            scrollDirection: Axis.horizontal,
            itemCount: snapshot.data.length,
            itemBuilder: (BuildContext context, int index) {
              return GestureDetector(
                onTap: () {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => EveryProjectPage(
                                snapshot.data[index],
                                snapshot.data[index].id,
                              )));
                },
                child: Card(
                  margin: EdgeInsets.only(right: 20),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(18)),
                  child: Container(
                    width: 270,
                    child: Column(
                      children: <Widget>[
                        //TOP PART
                        Container(
                          margin: EdgeInsets.only(top: 10, left: 10),
                          child: Row(
                            children: <Widget>[
                              Container(
                                child: Icon(
                                  Icons.account_circle,
                                  color: Colors.cyan,
                                ),
                                margin: EdgeInsets.only(right: 10),
                              ),
                              Container(
                                child: Icon(
                                  Icons.more_vert,
                                  color: Colors.black54,
                                ),
                                margin: EdgeInsets.only(right: 5),
                              ),
                              DisplayPercentageLinearly(
                                  snapshot.data[index].id)
                            ],
                          ),
                        ),

                        //CIRCLE AVATARS
                        Container(
                            alignment: Alignment.centerLeft,
                            margin: EdgeInsets.only(
                                top: 15, left: 12, right: 8),
                            height: 40,
                            child: FutureBuilder<List<Project>>(
                                future: _getProjects(),
                                builder: (context, snapshot) {
                                  if (!snapshot.hasData)
                                    return Container(
                                        width: 20,
                                        height: 20,
                                        alignment: Alignment.centerLeft,
                                        child: CircularProgressIndicator());
                                  return ListView.builder(
                                    scrollDirection: Axis.horizontal,
                                    itemCount:
                                        snapshot.data[index].users.length,
                                    itemBuilder: (context, index) {
                                      var users =
                                          snapshot.data[index].users;

                                      if (users == null) {
                                        return makeAvatar('?');
                                      }

                                      return Row(
                                        children: users
                                            .map<CircleAvatar>((e) =>
                                                makeAvatar(e['username']))
                                            .toList(),
                                      );
                                    },
                                  );
                                })),

                        Container(
                          margin: EdgeInsets.only(top: 75, left: 20),
                          alignment: Alignment.centerLeft,
                          child: Text(
                              "You have ${snapshot.data[index].days_left} days left"),
                        ),

                        //TEXT PART
                        Container(
                          alignment: Alignment.centerLeft,
                          margin:
                              EdgeInsets.only(left: 20, right: 15, top: 6),
                          child: Text(
                            "${snapshot.data[index].title[0].toString().toUpperCase()}"
                                "${snapshot.data[index].title.toString().substring(1)}",
                            style: TextStyle(
                                color: Colors.black87,
                                fontWeight: FontWeight.w500,
                                fontSize: 18),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              );
            });
    });
  }
} 

class DisplayPercentageLinearly extends StatefulWidget {
  final int id;

  DisplayPercentageLinearly(this.id);

  @override
  _DisplayPercentageLinearlyState createState() =>
  _DisplayPercentageLinearlyState(this.id);
}

   class _DisplayPercentageLinearlyState extends       State<DisplayPercentageLinearly> {
  //ID
  final int id;

   _DisplayPercentageLinearlyState(this.id);

    @override
   Widget build(BuildContext context) {
 return LinearPercentIndicator(
  width: 175,
  lineHeight: 13,
  percent: 0.2,
  backgroundColor: Colors.black12,
  progressColor: Colors.amber,
  center: Text(
    "",
    style: TextStyle(color: Colors.white),
    ),
   );
    }
}

【问题讨论】:

  • 每个项目的第一个用户名是hugo。诚然,第一个项目有第二个用户名 studentone。但是由于每个项目的列表视图中只有一行,并且从每个项目中获取第一个项目用户名,因此您应该期望每行有 3 行,每行都有一个 H 头像。
  • 如何将其更改为在每个用户名中显示第一个字母?
  • H 应该出现多少次?一次还是3次?无论哪种方式,您都需要预处理Projects 列表以提取用户名列表。遍历项目列表,然后在users 的内部循环中将每个用户名添加到列表(允许重复)或Set 将吞下重复项。然后使用该列表来填充您的列表视图。 (很难理解您想要什么,因为您没有具体说明您希望如何处理项目 81,该项目有两个用户,而其他项目只有一个。)
  • 所以我现在更新了JSON,也许你可以看到有三个项目,这些将显示在带有listview.builder的未来构建器中。在每个单元格内都会有另一个列表视图显示一个 CircleAvatar,其中包含该特定项目中用户的第一个字母。所以第一个:'H'和'S',第二个'H',第三个'H'
  • 我还链接了一张显示应用外观的图片,这是项目管理,因此 CircleAvatars 是分配给该特定项目的用户!

标签: json api listview indexing flutter


【解决方案1】:

我误解了你的问题,我重新表述了我的答案以实际回答你的问题。

新答案:

如果您想遍历var users,如果var users 是一个列表,您可以使用map() 函数。

你可以使用这个:

itemBuilder: (context, index) {
  var users = snapshot.data[index].users;
  return Column( // It doesn't need to be Column, it can be any widget with a children attribute.
    children: users.map((var user) {
      return CircleAvatar(
        foregroundColor: Colors.white,
        backgroundColor: Colors.blue,
        child: Text(user['username'].substring(0,1).toUpperCase()),
      );
    }).toList(),
  );
},

说明

让我解释一下代码:我们需要返回一个带有 children 属性的小部件,因为作为孩子,我们为每个用户返回一个带有 CircularAvatar() 小部件的 List。在这种情况下,我们使用 Column() 小部件。

在我们称为users.map() 的children 属性中,这将遍历用户中的每个用户。 map() 带有一个回调函数,该回调函数将为用户 List 中的每个项目执行。并且该回调函数接受一个参数,该参数是 List 的项目。

在回调函数中,我们现在可以返回一个CircularAvatar(),并且作为孩子,我们返回一个Text() 小部件。作为参数,我们调用user['username'] 来获取迭代时当前用户的用户名。然后我们调用substring(0,1)来获取用户名的第一个字母。最后我们调用toUpperCase() 来确保字母是大写的。

完整代码:

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;
              return Column(
                children: users.map((var user) {
                  return CircleAvatar(
                    foregroundColor: Colors.white,
                    backgroundColor: Colors.blue,
                    child: Text(user['username'].substring(0,1).toUpperCase()),
                  );
                }).toList(),
              );
            },
          );
        },
      ),
    );
  }
}

希望我现在明白了,这对你有帮助。

【讨论】:

  • 谢谢,但它仍然在每个单元格中只显示一个“H”。我希望它显示正在从事该项目的用户。对于这个项目,Hugo 和 Studentone 应该是 'H' 和 'S' :)
【解决方案2】:

var users = snapshot.data[index].users; 给你用户列表,你应该迭代那些构建列表的增益,你只是得到列表的第一项。

String username = ... users[0]['username'] ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 2018-09-20
    • 1970-01-01
    • 2016-01-25
    • 2011-10-27
    • 2022-06-13
    • 2013-06-14
    相关资源
    最近更新 更多