【问题标题】:Flutter Stateful code problem. What to put in setstate?Flutter 有状态的代码问题。在 setstate 中放什么?
【发布时间】:2019-06-28 19:59:51
【问题描述】:

我从不久前开始学习颤振。我非常了解编码,但我仍然有一些问题要理解有状态以及将什么放入创建状态。按照教程,我制作了这个应用程序,它加载一个带有地震信息的 json,并显示在一个侧面有滚动条的 ListView 中。现在我想让它成为一个有状态的小部件和 onrefresh 来更新来自 json 的值。这是我的代码(无状态) `

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';

Map _quakes;
List _features; // oggesto list delle features
void main() async {
  _quakes = await getQuakes();
  _features = _quakes["features"];
  runApp(new MaterialApp(
    theme: new ThemeData(
      accentColor: Colors.red,
    ),
    debugShowCheckedModeBanner: false,
    color: Colors.red,
    title: "Terremoti",
    home: new Quakes(),
  ));
}

class Quakes extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Tutti i Terremoti ultime 24h"),
        centerTitle: true,
        backgroundColor: Colors.red,
      ),
      body: new Center(
          child: new Scrollbar(
        child: RefreshIndicator(
          onRefresh: getQuakes,
          child: ListView.builder(
              itemCount: _features.length,
              padding: const EdgeInsets.all(15.0),
              itemBuilder: (BuildContext context, position) {
                if (position.isOdd)
                  return new SizedBox(
                    height: 10.0,
                    child: new Center(
                      child: new Container(
                        margin: new EdgeInsetsDirectional.only(
                            start: 1.0, end: 1.0),
                        height: 2.5,
                        color: Colors.red,
                      ),
                    ),
                  );
                final index = position ~/ 2;
                var format = new DateFormat("dd MMM, yyyy, \n" + "HH:mm:ss");
                //var dateString = format.format(format);
                var date = format.format(
                    new DateTime.fromMillisecondsSinceEpoch(
                        _features[index]["properties"]["time"],
                        isUtc: true));
                //creando le righe della listview
                return new ListTile(
                  title: new Text(
                    "Magnitudo: ${_features[index]["properties"]["mag"]} \n $date",
                    style: new TextStyle(
                        fontSize: 21.0,
                        color: Colors.green,
                        fontWeight: FontWeight.w700),
                  ),
                  subtitle: new Text(
                    "Luogo: ${_features[index]["properties"]["place"]}",
                    style: new TextStyle(
                      fontSize: 18.0,
                    ),
                  ),
                );
              }),
        ),
      )),
    );
  }
}

Future<Map> getQuakes() async {
  String apiUrl =
      "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson";
  http.Response response = await http.get(apiUrl);
  return json.decode(response.body);
}

`

【问题讨论】:

    标签: listview mobile dart flutter


    【解决方案1】:

    提取代码以重新加载列表,并使其成为State 类的实例方法。接下来,允许列表为空(显示进度指示器)。最后从initState调用reload方法。

    import 'dart:async';
    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'package:intl/intl.dart';
    
    void main() async {
      runApp(MaterialApp(
        theme: ThemeData(
          accentColor: Colors.red,
        ),
        debugShowCheckedModeBanner: false,
        color: Colors.red,
        title: 'Terremoti',
        home: Quakes(),
      ));
    }
    
    class Quakes extends StatefulWidget {
      @override
      State createState() => QuakesState();
    }
    
    class QuakesState extends State<Quakes> {
      DateFormat format = DateFormat('dd MMM, yyyy, \nHH:mm:ss');
      List _features;
    
      @override
      void initState() {
        super.initState();
        reload();
      }
    
      Future<void> reload() async {
        final Map quakes = await getQuakes();
        setState(() {
          _features = quakes['features'];
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Tutti i Terremoti ultime 24h'),
            centerTitle: true,
            backgroundColor: Colors.red,
          ),
          body: Center(
            child: _features == null
                ? const CircularProgressIndicator()
                : Scrollbar(
                    child: RefreshIndicator(
                      onRefresh: reload,
                      child: ListView.builder(
                          itemCount: _features.length,
                          padding: const EdgeInsets.all(15.0),
                          itemBuilder: (BuildContext context, position) {
                            if (position.isOdd)
                              return SizedBox(
                                height: 10.0,
                                child: Center(
                                  child: Container(
                                    margin: const EdgeInsetsDirectional.only(
                                      start: 1.0,
                                      end: 1.0,
                                    ),
                                    height: 2.5,
                                    color: Colors.red,
                                  ),
                                ),
                              );
                            final int index = position ~/ 2;
    
                            final String date = format.format(
                                DateTime.fromMillisecondsSinceEpoch(
                                    _features[index]['properties']['time'],
                                    isUtc: true));
                            //creando le righe della listview
                            return ListTile(
                              title: Text(
                                "Magnitudo: ${_features[index]["properties"]["mag"]} \n $date",
                                style: const TextStyle(
                                    fontSize: 21.0,
                                    color: Colors.green,
                                    fontWeight: FontWeight.w700),
                              ),
                              subtitle: Text(
                                "Luogo: ${_features[index]["properties"]["place"]}",
                                style: const TextStyle(
                                  fontSize: 18.0,
                                ),
                              ),
                            );
                          }),
                    ),
                  ),
          ),
        );
      }
    }
    
    Future<Map> getQuakes() async {
      final http.Response response = await http.get(
          'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson');
      return json.decode(response.body);
    }
    

    【讨论】:

    • 非常感谢。我将检查代码以理解它。但是如何更改滚动条的颜色甚至其他一些属性?比如宽度或者在它消失之前应该保留多少时间?
    • 通常,使用材料设计小部件,这些类型的设置由材料设计规范设置,颤振小部件遵循它们。如果您查看ScrollBar 的源代码,您会发现它们是文件const double _kScrollbarThickness = 6.0; const Duration _kScrollbarFadeDuration = Duration(milliseconds: 300); const Duration _kScrollbarTimeToFade = Duration(milliseconds: 600); 顶部的常量。顺便说一句,似乎很少使用带有ListView 的滚动条,它会自行滚动,但没有关于其运动范围的反馈。
    • 非常感谢。您的帮助真的很有帮助。
    • 如果有帮助,别忘了“接受”答案。
    • 一些问题... InitState 每次应用打开时都会调用?甚至从只是背景不完全开始? Future重载不能是Future?因为它只更新数据但不返回任何内容。你能给我一个学习路径,以便更好地学习颤振吗?太多的视频太多的教程,有时我会有点困惑。你是怎么学的?再次感谢
    猜你喜欢
    • 1970-01-01
    • 2021-01-02
    • 2011-06-02
    • 2020-10-09
    • 2017-04-08
    • 1970-01-01
    • 2019-05-19
    • 2011-09-12
    • 1970-01-01
    相关资源
    最近更新 更多