Flutter:如何从JSON自定义标题 [英] Flutter: How to custom Header from JSON
问题描述
我有一个这样的JSON文件(
所以请帮帮我,如果可能的话使用 StickyHeader
或 SliverAppBar
那么好,这是主文件:
import'package:问/模型/page3_model.dart';
import‘package:ask / services / page3_services.dart’;
导入的 package:flutter / material.dart;
类Page3扩展了StatefulWidget {
@override
_Page3State createState()=> _Page3State();
}
类_Page3State扩展了State< Page3> {
List< Header> _header = [];
@override
void initState(){
super.initState();
HeaderServices.getHeader()。then((header){
setState((){
_header = header;
});
}) ;
}
@override
小部件构建(BuildContext上下文){
return Scaffold(
appBar:AppBar(title:Text('Header')) ,
正文:Container(),
);
}
}
就像您的帖子主要是代码;请添加更多详细信息。 =。= ..............................................
自此以来,我们可以看到与相关的信息不止一个例如,对于
具有北美洲
的continentName countryFlag
, countryCode
, countryName,这是唯一的。因此,我们将以这种格式保留 newData
{
北美: [
[countryFlag,countryCode,countryName],
[countryFlag,countryCode,countryName]
]
}
...
所以,这就是我们使用新的 Map
来存储上面的值的方法表示形式
地图_newMap = {};
//将存储数据的新Map
// _data是存储JSON数组的变量名
_data.forEach((elem){
if (_newMap.containsKey(elem [ continentName]])){
_newMap [elem [ continentName]]。add([elem [ countryFlag],elem [ countryName],elem [ countryCode]]);
} else {
//数组数组将像这样存储:
_newMap [elem [ continentName]] = [[elem [ ; countryFlag],elem [ countryName],elem [ countryCode]]];
}
});
print(_newMap);
/ *
输出
{北美:[[https://www.countryflags.io/us/shiny/64.png,美国,美国],[ https://www.countryflags.io/ca/shiny/64.png,加拿大,加拿大]],南美:[[https://www.countryflags.io/br/shiny/64.png,巴西,巴西],[https://www.countryflags.io/in/shiny/64.png,印度,印第安纳州]],欧洲:[[https://www.countryflags.io/gb/shiny/64.png,美国王国,GB],[https://www.countryflags.io/de/shiny/64.png,德国,德国]]}
* /
看到!因此,对于每个 continentName
,我们可以有一个数组数组,其中包含要显示在特定 continentName $ c下的不同项目。 $ c>
有了,这是您的最终解决方案:
class _MyHomePageState扩展State< MyHomePage> ; {
List< Map> _data = [
{
continentName:北美,
countryFlag: https://www.countryflags.io/us/shiny/64。 png,
countryCode: US,
countryName: United States
},
{
continentName:北美,
countryFlag: https://www.countryflags.io/ca/shiny /64.png、
countryCode:CA、
countryName:Canada
},
{
continentName:南美,
countryFlag: https://www.countryflags.io/br/shiny /64.png、
countryCode:BR、
countryName:Brazil
},
{
continentName:南美,
countryFlag: https://www.countryflags.io/in/shiny /64.png、
countryCode:IN、
countryName:India,
},
{
continentName:欧洲,
countryFlag: https://www.countryflags.io/gb/shiny/ 64.png,
countryCode: GB,
countryName: United Kingdom
},
{
continentName:欧洲,
countryFlag: https://www.countryflags.io/de/shiny/ 64.png,
countryCode: DE,
countryName: Germany
}
];
//这将给出带有标题和数据的最终小部件
Widget get myWidget {
//由所有小部件组成
List< Widget> _widget = [];
Map _newMap = {};
//将存储数据
的新Map _data.forEach((elem){
if(_newMap.containsKey(elem [ continentName]])){
_newMap [elem [ continentName]]。add([elem [ countryFlag],elem [ countryName],elem [ countryCode]]));
} else {
//数组数组将像这样存储:
_newMap [elem [ continentName]] = [[elem [ countryFlag],elem [ countryName],elem [ ; countryCode]]];
}
});
_newMap.forEach((k,v){
List< Widget> _subHeaderItems = [];
_widget.add(
Container(
颜色:Colors.grey,
宽度:double.infinity,
子对象:Text(k,textAlign:TextAlign.center)
)
);
//我们得到类似以下项的项目=> [countryName,countryCode,countryFlag]
v.forEach((item){
_subHeaderItems.add(
Row(
mainAxisAlignment:MainAxisAlignment.start,
子级:< Widget> [
SizedBox(width:10.0),
Image.network(
item [0],
宽度:30.0,
高度:20.0
),
SizedBox(宽度:20.0),
Text(项目[2]),
SizedBox(宽度: 35.0),
文本(item [1]),
]
)
);
_subHeaderItems.add(
Divider(height:1.0,color:Colors.grey [300])
);
});
_widget.add(
Column(
crossAxisAlignment:CrossAxisAlignment.stretch,
子级:_subHeaderItems
)
);
});
return Column(
crossAxisAlignment:CrossAxisAlignment.stretch,
子级:_widget
);
}
@override
Widget build(BuildContext context){
return Scaffold(
appBar:AppBar(
title :Text(widget.title),
),
正文:Container(
高度:double.infinity,
宽度:double.infinity,
子级:this。 myWidget
)
);
}
}
您将获得的结果
希望有帮助:)
I have a JSON file like this (link API):
[
{
"continentName": "North America",
"countryFlag": "https://www.countryflags.io/us/shiny/64.png",
"countryCode": "US",
"countryName": "United States"
},
{
"continentName": "North America",
"countryFlag": "https://www.countryflags.io/ca/shiny/64.png",
"countryCode": "CA",
"countryName": "Canada"
},
{
"continentName": "South America",
"countryFlag": "https://www.countryflags.io/br/shiny/64.png",
"countryCode": "BR",
"countryName": "Brazil"
},
{
"continentName": "South America",
"countryFlag": "https://www.countryflags.io/in/shiny/64.png",
"countryCode": "IN",
"countryName": "India"
},
{
"continentName": "Europe",
"countryFlag": "https://www.countryflags.io/gb/shiny/64.png",
"countryCode": "GB",
"countryName": "United Kingdom"
},
{
"continentName": "Europe",
"countryFlag": "https://www.countryflags.io/de/shiny/64.png",
"countryCode": "DE",
"countryName": "Germany"
}
I want to show header of same "continentName" (Ex: North America; South America; Europe) like this
So pls help me, if possible to use StickyHeader
or SliverAppBar
then great, this is main file:
import 'package:ask/model/page3_model.dart';
import 'package:ask/services/page3_services.dart';
import 'package:flutter/material.dart';
class Page3 extends StatefulWidget {
@override
_Page3State createState() => _Page3State();
}
class _Page3State extends State<Page3> {
List<Header> _header = [];
@override
void initState() {
super.initState();
HeaderServices.getHeader().then((header) {
setState(() {
_header = header;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Header')),
body: Container(),
);
}
}
"It looks like your post is mostly code; please add some more details". =.= ...........................................
Since, we can see that there are more than one info related to a continentName
, for example, for North America
has countryFlag
, countryCode
, 'countryName' respectively, and that is unique. So we will keep our newData
in this format
{
North America: [
[countryFlag, countryCode, countryName],
[countryFlag, countryCode, countryName]
]
}
...
So, this is how we will do that using our new Map
which will store the value like the above representation
Map _newMap = {};
// new Map which will store the data
// _data is the variable name which stores your JSON Array
_data.forEach((elem){
if(_newMap.containsKey(elem["continentName"])){
_newMap[elem["continentName"]].add([elem["countryFlag"], elem["countryName"], elem["countryCode"]]);
}else{
// Array of arrays will be stored like this
_newMap[elem["continentName"]] = [[elem["countryFlag"], elem["countryName"], elem["countryCode"]]];
}
});
print(_newMap);
/*
OUTPUT
{North America: [[https://www.countryflags.io/us/shiny/64.png, United States, US], [https://www.countryflags.io/ca/shiny/64.png, Canada, CA]], South America: [[https://www.countryflags.io/br/shiny/64.png, Brazil, BR], [https://www.countryflags.io/in/shiny/64.png, India, IN]], Europe: [[https://www.countryflags.io/gb/shiny/64.png, United Kingdom, GB], [https://www.countryflags.io/de/shiny/64.png, Germany, DE]]}
*/
See that! So, the idea is for every continentName
, we can have array of arrays which will contain different item to be shown under a specific continentName
With that, here is final solution for you:
class _MyHomePageState extends State<MyHomePage> {
List<Map> _data = [
{
"continentName": "North America",
"countryFlag": "https://www.countryflags.io/us/shiny/64.png",
"countryCode": "US",
"countryName": "United States"
},
{
"continentName": "North America",
"countryFlag": "https://www.countryflags.io/ca/shiny/64.png",
"countryCode": "CA",
"countryName": "Canada"
},
{
"continentName": "South America",
"countryFlag": "https://www.countryflags.io/br/shiny/64.png",
"countryCode": "BR",
"countryName": "Brazil"
},
{
"continentName": "South America",
"countryFlag": "https://www.countryflags.io/in/shiny/64.png",
"countryCode": "IN",
"countryName": "India"
},
{
"continentName": "Europe",
"countryFlag": "https://www.countryflags.io/gb/shiny/64.png",
"countryCode": "GB",
"countryName": "United Kingdom"
},
{
"continentName": "Europe",
"countryFlag": "https://www.countryflags.io/de/shiny/64.png",
"countryCode": "DE",
"countryName": "Germany"
}
];
// This will give out our final widget with header and data
Widget get myWidget{
// Consists of all the Widgets
List<Widget> _widget = [];
Map _newMap = {};
// new Map which will store the data
_data.forEach((elem){
if(_newMap.containsKey(elem["continentName"])){
_newMap[elem["continentName"]].add([elem["countryFlag"], elem["countryName"], elem["countryCode"]]);
}else{
// Array of arrays will be stored like this
_newMap[elem["continentName"]] = [[elem["countryFlag"], elem["countryName"], elem["countryCode"]]];
}
});
_newMap.forEach((k,v){
List<Widget> _subHeaderItems = [];
_widget.add(
Container(
color: Colors.grey,
width: double.infinity,
child: Text(k, textAlign: TextAlign.center)
)
);
// We get the item like this item => [countryName, countryCode, countryFlag]
v.forEach((item){
_subHeaderItems.add(
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: 10.0),
Image.network(
item[0],
width: 30.0,
height: 20.0
),
SizedBox(width: 20.0),
Text(item[2]),
SizedBox(width: 35.0),
Text(item[1]),
]
)
);
_subHeaderItems.add(
Divider(height: 1.0, color: Colors.grey[300])
);
});
_widget.add(
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: _subHeaderItems
)
);
});
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: _widget
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
height: double.infinity,
width: double.infinity,
child: this.myWidget
)
);
}
}
RESULT YOU WILL GET
Hope that helps :)
这篇关于Flutter:如何从JSON自定义标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!