Flutter-抽屉和Listview.Builder()错误

时间:2020-03-07 15:43:42

标签: flutter

这是我的代码:


import 'dart:async';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
//import 'package:location/location.dart';
class Home extends StatefulWidget {
  Home({Key key, this.title}) : super(key: key);
  final String title;

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

class _Home extends State<Home> {
  //declared var
  String key = "ville";
  String txt_ville = "PARIS";
  List<String> villes = [];
  GlobalKey<ScaffoldState> _drawerKey = GlobalKey();

 //Location location;
  //LocationData locationData;
  //Stream<LocationData> stream;



  @override
  void initState() {
    // TODO: implement initState
    getData();
    print(villes);
    super.initState();

    //location = new Location();
    //getFirstLocation();
  }

  /*getFirstLocation() async {
    try {
      print("Position: ${locationData.latitude}/${locationData.longitude}");
    }catch (e) {
      print("Error when locating $e");
    }
  }*/

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        key: _drawerKey,
      drawer: Drawer(
        child: new ListView.builder(
          itemCount: villes.length,
          itemBuilder: (BuildContext ctx, i) {
            return new ListTile(title: new Text(villes[i]));
          },
        )
      ),


        backgroundColor: Colors.amberAccent,
      body: new Column(
        children: <Widget>[
          Expanded(
            flex:4,
            child: new Container(
              width: double.infinity,
              decoration: new BoxDecoration(
                  color: Colors.white,
                borderRadius: new BorderRadius.only(bottomLeft: Radius.circular(120))
              ),
              child: new Column(
                children: <Widget>[
                  new Padding(
                    padding: EdgeInsets.only(top: 50),
                    child: new Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[

                        new Padding(padding: EdgeInsets.only(left: 20),
                        child: new IconButton(icon: new Icon(Icons.dehaze, size: 30, color: Colors.black,), onPressed: () {
                          _drawerKey.currentState.openDrawer();
                        })),
                        new Padding(
                          padding: EdgeInsets.only(left: 30),
                          child: new Text("TheWeatherApp", style: new TextStyle(
                              fontSize: 40
                            ),),
                        ),


                    ]),
                  )
                ],
              ),
            )
          ),
          Expanded(
            flex: 1,
            child: new Container(
            ),
          )
        ],
      )
    );
  }

  Future<Null> addTown() async{
    return showDialog(barrierDismissible: true, context: context, builder: (BuildContext buildcontext) {
      return new SimpleDialog(
        contentPadding: EdgeInsets.all(20.0),
        title: Text("Add a town"),
        children: <Widget>[
          new RaisedButton(onPressed: () {

          }, child: new Text("Auto locate me"),),
          new TextField(
            decoration: new InputDecoration(
              labelText: "Ville"
            ),
            onSubmitted: (s) {
              setData(s);
              Navigator.pop(context);
            },
          )
        ],
      );
    });
  }

  void getData() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    List<String> liste = await sharedPreferences.getStringList(key);
    if (liste != null) {
      setState(() {
        villes = liste;
      });
    }
  }

  void setData(String str) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    villes.add(str);
    await sharedPreferences.setStringList(key, villes);
    getData();
  }

  void deleteData(String str) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    villes.remove(str);
    await sharedPreferences.setStringList(key, villes);
  }
}

我仍然是Flutter的初学者,我想了解为什么在模拟器上启动应用程序并使用图标按钮打开抽屉时出现此错误:Pastbinlink to error

如果我故意在代码中创建错误,例如删除括号并执行hotreload,然后放回括号并再次执行hotreload,那么我的代码将起作用并显示列表视图...

我有一种理论认为,是我的getData函数初始化了不起作用的变量villes ...

在此先感谢您的答复!

1 个答案:

答案 0 :(得分:0)

我无法发表评论,因此我将其写为答案。

我还没有尝试过您的代码,但是不确定是否可以使用

您应该尝试使用FutureBuilder

SharedPreferences.getInstance()是将来会有价值的未来,并且当您尝试构建抽屉时,它会尝试访问不存在的值。

相反,如果您这样尝试。检索数据后,便会创建您的抽屉。

drawer: Drawer(
    child: new FutureBuilder<List<String>>(
            future: getData(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                if (snapshot.data.length == 0) {
                  return Center(child: Text("No data found."));
                } else {
                  return ListView.builder(
                    itemCount: snapshot.data.length,
                    itemBuilder: (BuildContext ctx, i) {
                      return new ListTile(title: new Text(villes[i]));
                    },
                  )
                }
          } else if (snapshot.hasError) {
            return checkError();
          }
          // By default, show a loading spinner.
          return Center(child: CircularProgressIndicator());
        }) 
    ),