Flutter TreeView Json数据解析
问题内容:
我想在我的flutter应用程序中使用此flutter treeview小部件来构建公司treeview
https://pub.dev/packages/tree_view
我有一个以树状结构列出公司的网络服务。
https://washservice.com/api/companyXML/1fe5bae2-331a-4080-b34f-5ebd3518efd8
我已经编写了具有递归功能的json解析代码以构建treeview,但是它无法正常工作。有人可以帮助我修复解析问题并构建treeview小部件吗?
这是我的代码
import 'dart:async';
import 'dart:convert';
import 'package:example/models/Company.dart';
import 'package:example/widgets/directory_widget.dart';
import 'package:example/widgets/file_widget.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:tree_view/tree_view.dart';
class CompaniesPage extends StatefulWidget {
CompaniesPage({Key key, this.title}) : super(key: key);
final String title;
@override
_CompaniesPageState createState() => _CompaniesPageState();
}
class _CompaniesPageState extends State<CompaniesPage> {
List<Company> companiesList = new List<Company>();
@override
void initState() {
super.initState();
// Loading initial data or first request to get the data
_getTeeViewData1();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title ?? 'Tree View demo'),
),
body: Center(
child: TreeView(
startExpanded: false,
children: _getChildList(companiesList),
),
),
);
}
// Webservice request to load 20 users data using paging
Future<List<Company>> _getTeeViewData1() async {
String url =
"https://washservice.com/api/companyXML/1fe5bae2-331a-4080-b34f-5ebd3518efd8";
print(url);
var response = await http.get(url);
var jsonData = json.decode(response.body);
print(jsonData);
var data = jsonData["Companies"];
var companies = data["Company"];
print(companies);
Company c = new Company();
c.CompanyId = companies["CompanyId"];
c.CompanyName = companies["CompanyName"];
c.ParentId = companies["ParentId"];
c.CostCenter = '${companies["CostCenter"] ?? ""}';
c.IsSelectableforMovement = companies["IsSelectableforMovement"];
c = getChildCompanies(companies["Company"], c);
companiesList.add(c);
return companiesList;
}
Company getChildCompanies(childCompanies, parentCompany) {
if (childCompanies != null) {
for (var childCompany in childCompanies) {
Company childCO = new Company();
childCO.CompanyId = childCompany["CompanyId"];
childCO.CompanyName = childCompany["CompanyName"];
childCO.ParentId = childCompany["ParentId"];
childCO.CostCenter = '${childCompany["CostCenter"] ?? ""}';
childCO.IsSelectableforMovement =
childCompany["IsSelectableforMovement"];
Company c2 = getChildCompanies(childCompany["Company"], childCO);
parentCompany.company.add(c2);
return parentCompany;
}
}
}
List<Widget> _getChildList(List<Company> childDocuments) {
return childDocuments.map((document) {
if (document.company.length != 0) {
return Container(
margin: EdgeInsets.only(left: 8),
child: TreeViewChild(
parent: _getDocumentWidget(document: document),
children: _getChildList(document.company),
),
);
}
return Container(
margin: const EdgeInsets.only(left: 4.0),
child: _getDocumentWidget(document: document),
);
}).toList();
}
Widget _getDocumentWidget({@required Company document}) =>
document.company.length == 0
? _getFileWidget(document: document)
: _getDirectoryWidget(document: document);
DirectoryWidget _getDirectoryWidget({@required Company document}) =>
DirectoryWidget(directoryName: document.CompanyName);
FileWidget _getFileWidget({@required Company document}) =>
FileWidget(fileName: document.CompanyName);
}
公司
class Company {
Company();
String CompanyId;
String CompanyName;
String ParentId;
String CostCenter;
String IsSelectableforMovement;
List<Company> company = new List<Company>();
}
问题答案:
我对自己的json数据使用了相同的包。在这里您可以找到用法示例。也许您可以对其进行调整以供使用。
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:tree_view/tree_view.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'title',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/',
routes: {
'/': (context) => TestPage(),
},
);
}
}
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
String responseBody =
'{ "id": 0,"name": "A","children": [{ "id": 1, "name": "Aa","children": [{"id": 2,"name": "Aa1","children": null}]},{ "id": 3, "name": "Ab","children": [{"id": 4,"name": "Ab1","children": null},{"id": 5,"name": "Ab2","children": null}]}]}';
@override
Widget build(BuildContext context) {
Map mapBody = jsonDecode(responseBody);
return SafeArea(
child: Scaffold(
body: printGroupTree(
mapBody,
),
),
);
}
Widget printGroupTree(
Map group, {
double level = 0,
}) {
if (group['children'] != null) {
List<Widget> subGroups = List<Widget>();
for (Map subGroup in group['children']) {
subGroups.add(
printGroupTree(
subGroup,
level: level + 1,
),
);
}
return Parent(
parent: _card(
group['name'],
level * 20,
),
childList: ChildList(
children: subGroups,
),
);
} else {
return _card(
group['name'],
level * 20,
);
}
}
Widget _card(
String groupName,
double leftPadding,
) {
return Container(
padding: EdgeInsets.only(
left: leftPadding + 5,
right: 20,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0),
),
height: 100,
child: Row(
children: <Widget>[
Container(
width: 250,
child: Row(
children: <Widget>[
Container(
height: 70,
width: 70,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a6/Rubik%27s_cube.svg/220px-Rubik%27s_cube.svg.png',
),
),
),
),
SizedBox(
width: 10,
),
Flexible(
child: Text(
'SomeText',
),
),
],
),
),
Expanded(
child: SizedBox(),
),
InkWell(
//TODO:Empty method here
onTap: () {},
child: Icon(
Icons.group_add,
size: 40,
),
)
],
),
);
}
}