Flutter:如何从JSON自定义标题 [英] Flutter: How to custom Header from JSON

查看:85
本文介绍了Flutter:如何从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


有了,这是您的最终解决方案:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆