循环遍历json文件以显示dart/flutter中嵌套的信息



我有一个json文件结构如下:

资产/data.json

data = {
users: [
{
id: 'u1',
name: 'John',
},
{
id: 'u2',
name: 'Fred',
},
{
id: 'u3',
name: 'Robert',
}
],
threads: [
{
id: 't1',
title: 'What is your favorite dog breed ?',
publishedAt: 19191919191,
posts: ['p1', 'p2'],
userId: ''
}
{
id: 't2',
title: 'What is your favorite cat breed ?',
publishedAt: 17171717171,
posts: ['p3'],
userId: ''
}
]
posts: [
{
id: 'p1',
publishedAt: 19191919191,
userId: 'u1',
text: 'Golden Retriever',
threadId: 't1'
}
{
id: 'p2',
publishedAt: 11111111111,
userId: 'u2',
text: 'Spitz',
threadId: 't1'
}
{
id: 'p3',
publishedAt: 16161616161,
userId: 'u3',
text: 'Persan',
threadId: 't2'
}
]
}

我的问题我想显示线程,然后循环帖子(与相关的用户名)为每个线程。我可以有很多线程和很多帖子。(我现在不处理分页,但它可能是有趣的,有你的想法在这个)

为了实现这一点,我使用了for循环和if条件语句。我不太相信。我看到ListView和ListView。builder(也许我可以嵌套几个ListView.builder)或groupBy,但我不知道使用它是否更好。

请找到我的代码,如果你能挑战它,为了使它更好,知道更好的实践,我将很高兴。

main.dart

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Forum',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HompePage(),
);
}
}
class HompePage extends StatefulWidget {
@override
_HompePageState createState() => _HompePageState();
}
class _HompePageState extends State<HompePage> {
List _threads = [];
List _posts = [];
List _users = [];
// Fetch content from the json file
Future<void> readJson() async {
final String response = await rootBundle.loadString('assets/data.json');
final data = await json.decode(response);
setState(() {
_threads = data['threads'] as List;
_posts = data['posts'] as List;
_users = data['users'] as List;
});
}
@override
void initState() {
super.initState();
readJson();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
for (var thread in _threads)
Column(
children: [
const SizedBox(height: 20),
Text(
thread["title"].toString(),
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 20),
for (var post in _posts)
if (post["threadId"] == thread["id"])
Column(
children: [
for (var user in _users)
if (post["userId"] == user["id"])
Column(
children: [
const SizedBox(height: 15),
Text(user["name"].toString()),
const SizedBox(height: 15),
],
),
Text(post["text"].toString()),
],
)
],
),
],
),
),
);
}
}

而不是

for (var user in _users)
if (post["userId"] == user["id"])
Column(
children: [
const SizedBox(height: 15),
Text(user["name"].toString()),
const SizedBox(height: 15),
],
),

你可以这样使用listView builder:

ListView.builder(
itemCount: _users.length,
itemBuilder: (context, index) {
return post["userId"] == _users[index]["id"]?
Column(
children: [
const SizedBox(height: 15),
Text(_users[index]["name"].toString()),
const SizedBox(height: 15),
],
):Container(); // in case post["userId"] != _users[index]["id"] you should return something for the list builder
}])

也你最好改变你的Json文件格式为这样的东西,以避免if子句:

threads: [
{
id: 't1',
title: 'What is your favorite dog breed ?',
publishedAt: 19191919191,
userId: ''
posts:[
{
id: 'p1',
publishedAt: 19191919191,
userId: 'u1',
text: 'Golden Retriever',
threadId: 't1'
}
]
}
]

最新更新