gpt4 book ai didi

flutter - Flutter:如何基于TabBar和ToggleButtons从JSON过滤数据?

转载 作者:行者123 更新时间:2023-12-03 04:44:27 25 4
gpt4 key购买 nike

我有一个像这样的JSON:

[
{
"continentName": "NA",
"isDayTime": true,
"seasonName": "Spring",
"cityName": "United States",
"xAlign": 45.4,
"yAlign": 69,
"cityTemperature": 27
},
{
"continentName": "NA",
"isDayTime": true,
"seasonName": "Spring",
"cityName": "Canada",
"xAlign": 35.7,
"yAlign": 53,
"cityTemperature": 16
},
{
"continentName": "NA",
"isDayTime": true,
"seasonName": "Summer",
"cityName": "Mexico",
"xAlign": 87.8,
"yAlign": 41.8,
"cityTemperature": 28
},
{
"continentName": "NA",
"isDayTime": false,
"seasonName": "Summer",
"cityName": "Cuba",
"xAlign": 55.3,
"yAlign": 88.8,
"cityTemperature": 27
},
{
"continentName": "EU",
"isDayTime": true,
"seasonName": "Winter",
"cityName": "Germany",
"xAlign": 33.8,
"yAlign": 38.8,
"cityTemperature": 3
}
]
我想显示过滤的数据,如下所示:
enter image description here
  • 第一个过滤器是TabBar(“continentName”)
  • 第二个过滤器是ToggleButtons(“isDayTime”)=>需要至少一个选择
  • 第三个过滤器是ToggleButtons(“listSeason”)=>互斥选择,但不允许选择任何按钮。

  • 当启动页面时,默认情况下, Tabbar被选择为“NA”,第一个 toggleButtons(“isDayTime”)被选择为“Day” => 我希望如果单击“Spring” =>它将显示令人满意的数据,具体来说就是“美国”和“加拿大”
    所以请帮助我,这是主文件:
    import 'package:ask/model/temperature_model.dart';
    import 'package:ask/services/temperature_service.dart';
    import 'package:flutter/material.dart';

    class CityTemperature extends StatefulWidget {
    CityTemperature() : super();
    @override
    _CityTemperatureState createState() => _CityTemperatureState();
    }

    class _CityTemperatureState extends State<CityTemperature> {
    List<Temperature> _temperature = [];
    List<bool> isDayTime = [true, false];
    List<bool> listSeason = [false, false, false, false];

    @override
    void initState() {
    super.initState();
    TemperatureServices.getTemperature().then((temperature) {
    setState(() {
    _temperature = temperature;
    });
    });
    }

    @override
    Widget build(BuildContext context) {
    return Container(
    child: DefaultTabController(
    length: 4,
    child: Scaffold(
    appBar: AppBar(
    title: Text('Temperature'),
    bottom: TabBar(tabs: [
    Tab(child: Text('NA')),
    Tab(child: Text('EU')),
    Tab(child: Text('Africa')),
    Tab(child: Text('Asia')),
    ]),
    ),
    body: Column(children: [
    Center(
    child: ToggleButtons(
    children: [Text('Day'), Text('Night')],
    onPressed: (int index) {
    setState(() {
    for (int buttonIndex = 0; buttonIndex < isDayTime.length; buttonIndex++) {
    if (buttonIndex == index) {
    isDayTime[buttonIndex] = true;
    } else {
    isDayTime[buttonIndex] = false;
    }
    }
    });
    },
    isSelected: isDayTime)),
    SizedBox(height: 5),
    Center(
    child: ToggleButtons(
    children: [Text('Spring'), Text('Summer'), Text('Autumn'), Text('Winter')],
    onPressed: (int index) {
    setState(() {
    for (int buttonIndex = 0; buttonIndex < listSeason.length; buttonIndex++) {
    if (buttonIndex == index) {
    listSeason[buttonIndex] = !listSeason[buttonIndex];
    } else {
    listSeason[buttonIndex] = false;
    }
    }
    });
    },
    isSelected: listSeason)),
    SizedBox(height: 5),
    Expanded(
    child: TabBarView(children: [
    Column(children: [ // How to display the satisfying data
    for (Temperature temp in _temperature)
    Row(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    children: [
    Text(temp.cityName),
    Text('${temp.cityTemperature.toString()}° C'),
    ],
    )
    ]),
    Column(), // How to display the satisfying data
    Column(), // How to display the satisfying data
    Column(), // How to display the satisfying data
    ]),
    )
    ]))));
    }
    }


    编辑1:
    我想添加两件事,如下所示:
    1.为每个TabBarView和每个_tabs添加背景图像isDayTime
  • 对于每个continentName,白天或黑夜都有2张图像。

  • enter image description here
  • 因为它是图像,所以我想将其放入Assets中,以使用户更快地加载。此外,为避免在json =>上创建更多数据,我将图像的文件名创建为:“na_day.png”或“na_true.png”,并通过Image.asset('assets/${temp.continentName}_${isDayTime}.png')或类似的
  • 进行访问

    2.根据图像的X Y百分比位置在背景图像上显示 cityName enter image description here
  • 我使用来自JSON的数据:xAlignyAlign来确定cityName在图像上的位置(已更新JSON)
  • 据我所知,似乎最好的方法是使用IntrinsicHeightStackAlign这样做:
  • class DisplayCountry extends StatelessWidget {
    final List<Temperature> countries;

    DisplayCountry({this.countries});

    @override
    Widget build(BuildContext context) {
    return Column(children: [
    for (Temperature temp in countries) // I don't know where to put this
    IntrinsicHeight(
    child: Stack(children: [
    Image.asset('assets/${temp.continentName}_${isDayTime}.png'.asset), // Or something like this
    Align(
    alignment: Alignment(temp.xAlign / 100 * 2 - 1, temp.yAlign / 100 * 2 - 1),
    child: Text(temp.cityName),
    ),
    ]),
    )
    ]);
    }
    }

    extension AssetsExtension on String {
    String get asset => this.toLowerCase().replaceAll(" ", "_").replaceAll("'", "_");
    }

    因此,请帮助我更新 class DisplayCountry以便能够结合上述两件事

    最佳答案

    像这样的东西

    class CityTemperature extends StatefulWidget {
    CityTemperature() : super();

    @override
    _CityTemperatureState createState() => _CityTemperatureState();
    }

    class _CityTemperatureState extends State<CityTemperature> {
    List<Temperature> _temperature = [];
    List<String> _tabs = [];
    Map<String, bool> isDayTime = {'Day': true, 'Night': false};
    Map<String, bool> listSeason = {'Spring': false, 'Summer': false, 'Autumn': false, 'Winter': true};

    @override
    void initState() {
    super.initState();
    var response = json.decode(jsonFile);
    _temperature = List<Temperature>.from(response.map((x) => Temperature.fromJson(x)));
    _tabs = _temperature.map<String>((x) => x.continentName).toSet().toList();
    /*
    TemperatureServices.getTemperature().then((temperature) {
    setState(() {
    _temperature = temperature;
    });
    });*/
    }

    @override
    Widget build(BuildContext context) {
    return DefaultTabController(
    length: _tabs.length,
    child: Scaffold(
    appBar: AppBar(
    title: Text('Temperature'),
    bottom: TabBar(
    tabs: _tabs.map((String name) => Tab(text: name)).toList()
    ),
    ),
    body: Column(children: [
    Center(
    child: ToggleButtons(
    children: isDayTime.keys.map((key) => Text(key)).toList(),
    onPressed: (int index) {
    String indexKey = isDayTime.keys.toList()[index];
    setState(() {
    isDayTime.updateAll(
    (key, value) => key == indexKey ? true : false);
    }
    );
    },
    isSelected: isDayTime.values.toList())),
    SizedBox(height: 5),
    Center(
    child: ToggleButtons(
    children: listSeason.keys.map((key) => Text(key)).toList(),
    onPressed: (int index) {
    String indexKey = listSeason.keys.toList()[index];
    setState(() {
    listSeason.updateAll(
    (key, value) => key == indexKey ?
    !listSeason[indexKey] : false);
    });
    },
    isSelected: listSeason.values.toList())),
    SizedBox(height: 5),
    Expanded(
    child: TabBarView(
    children: _tabs.map((String name) {
    return DisplayCountry(
    countries: List<Temperature>.from(_temperature)
    ..retainWhere((temperature) =>
    temperature.continentName == name
    && temperature.isDayTime == isDayTime['Day']
    && temperature.seasonName == listSeason.keys.firstWhere(
    (k) => listSeason[k] == true, orElse: () => 'Nothing'))
    );
    }).toList()
    ),
    )
    ]
    )
    )
    );
    }
    }

    class DisplayCountry extends StatelessWidget{
    final List<Temperature> countries;

    DisplayCountry({this.countries});

    @override
    Widget build(BuildContext context){
    return Column(
    children: [
    for(Temperature temp in countries)
    Row(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    children: [
    Text(temp.cityName),
    Text('${temp.cityTemperature.toString()}° C'),
    ],
    )
    ]
    );
    }
    }
    我创建了一个名为_tabs的列表,其中所有大陆名称均为_temperatures,然后将其添加到set和toList中。 toSet将其转换为一个集合,一个集合是一个不允许重复值的可迭代的集合,然后我将其转换回列表,这样我就有了一个唯一的continentName(NA,EU等)列表。
    在DefaultTabController中,我添加_tabs.length,在tabView中创建_tab.map列表,该列表创建DisplayCountry的小部件列表,我使用keepwhere来仅保留那些满足条件的小部件(与该标签中的那个便笺相同,与选择的那个相同的seasonName,如果为true,则为DayTime,否则为day晚上)
    enter image description here
    enter image description here
    更新
    class DisplayImage extends StatelessWidget {
    final List<Temperature> countries;
    final String continentName;
    final bool isDayTime;

    DisplayImage({this.countries , this.continentName, this.isDayTime});

    @override
    Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    return Stack(
    fit: StackFit.passthrough,
    children: [
    Image.asset('assets/$continentName_$isDayTime.png'.asset),
    fit: BoxFit.cover,),
    for (Temperature temp in countries)
    Positioned(
    left: temp.xAlign * size.width / 100.0,
    top: temp.yAlign / 2 * size.height / 100.0,
    child: Text('${temp.cityName} ${temp.cityTemperature.toString()}° C'),
    )
    ]);
    }
    }
    以及在TabView中调用它时
    TabBarView(
    children: _tabs.map((String name) {
    return DisplayImage(
    continentName: name,
    isDayTime: isDayTime['Day'],
    countries: List<Temperature>.from(_temperature)
    ..retainWhere((temperature) =>
    temperature.continentName == name &&
    temperature.isDayTime == isDayTime['Day'] &&
    temperature.seasonName ==
    listSeason.keys.firstWhere(
    (k) => listSeason[k] == true,
    orElse: () => 'Nothing')));
    }).toList())
    据我了解,您可以使用堆栈的fit属性(StackFit.passthrough),它的工作方式与InternalHeight相同。从文档中
    StackFit.passthrough 
    For example, if a Stack is an Expanded child of a Row, the horizontal constraints will be tight and the vertical constraints will be loose.
    在这种情况下,您将在列中使用“扩展”,因此它具有水平的松散和垂直的紧密性。然后做一些数学运算,如果定位不符合您的要求,请尝试“对齐”小部件

    关于flutter - Flutter:如何基于TabBar和ToggleButtons从JSON过滤数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62540501/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com