简体   繁体   English

如何从颤动的另一个飞镖文件中获取地图长度?

[英]How to get Map length from another dart file in flutter?

This is my code for main.dart file and map.dart file.这是我的 main.dart 文件和 map.dart 文件的代码。 Here I am trying to get the length of the Map<> contact from map.dart file in main.dart file after removing some keys from the Map<> contact by clicking "Remove element from map" Button in map.dart file.在这里,我试图通过单击 map.dart 文件中的“从地图中删除元素”按钮从 Map<> 联系人中删除一些键后,从 main.dart 文件中的 map.dart 文件中获取 Map<> 联系人的长度。 I created an object of class MyMap from map.dart in main.dart file to get the data of the Map.我从 main.dart 文件中的 map.dart 创建了一个 MyMap 类的对象,以获取 Map 的数据。 But I am getting the initial value of mapLength which is 0. But I expect that the output should be the length of the Map<> contact by clicking the raised button "Get length of map" in main.dart.但我得到了 mapLength 的初始值为 0。但我希望通过单击 main.dart 中凸起的按钮“获取地图长度”,输出应该是 Map<> 联系人的长度。

main.dart主要.dart

import 'package:flutter/material.dart';
import 'package:passing_length/map.dart';

void main() => runApp(new MyApp());


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  var mapPage = new MyMap();


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text(widget.title),
        ),
        body: new Center(
            child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Padding(
              padding: new EdgeInsets.all(20.00),
              child: new RaisedButton(
                onPressed: () {
                  print(mapPage.mapLength());
                },
                child: new Text("Get length of map"),
              ),
            ),
            new Padding(
              padding: new EdgeInsets.all(20.00),
              child: new RaisedButton(
                onPressed: () {
                  Navigator.push(
                    context,
                    new MaterialPageRoute(builder: (context) => new MyMap()),
                  );
                },
                child: new Text("Goto new Page"),
              ),
            ),
          ],
        )));
  }
}

map.dart地图.dart

class MyMap extends StatefulWidget {
  @override
  _MyMapState createState() => new _MyMapState();

  int mapLength() {
    return new _MyMapState().mapLength;
  }
}

class _MyMapState extends State<MyMap> {
  Map<String, int> contact = {
    "AAAA": 1111,
    "BBBB": 2222,
    "CCCC": 3333,
    "DDDD": 4444,
    "EEEE": 5555,
    "FFFF": 6666,
    "GGGG": 7777,
  };

  int mapLength = 0;

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "My Map",
      home: new Scaffold(
          appBar: new AppBar(title: new Text("My Map")),
          body: new Center(
              child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new Padding(
                padding: new EdgeInsets.all(20.00),
                child: new RaisedButton(
                  onPressed: () {
                    contact.remove(contact.keys.elementAt(contact.length - 1));
                    mapLength = contact.length;
                    print(mapLength);
                  },
                  child: new Text("Remove element from map"),
                ),
              ),
              new Padding(
                padding: new EdgeInsets.all(20.00),
                child: new RaisedButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: new Text("Go Back"),
                ),
              ),
            ],
          ))),
    );
  }
}

To understand why this doesn't work, I think you need a better understanding of how StatefulWidgets, States, and Stateless widgets work in Flutter.要理解为什么这不起作用,我认为您需要更好地了解 StatefulWidgets、States 和 Stateless 小部件在 Flutter 中是如何工作的。 I'd recommend going through Flutter's getting started codelab, especially the part on stateful widgets , and maybe spending a bit of time reading the stateful widget and state documentation.我建议通过 Flutter 的入门代码实验室,尤其是关于stateful widgets的部分,并且可能花一些时间阅读stateful widgetstate文档。

But the TLDR is as follows - the class that inherits StatefulWidget should pretty much only be used to store things passed in through the constructor, and should be immutable.但是 TLDR 如下 - 继承StatefulWidget的类应该几乎只用于存储通过构造函数传入的东西,并且应该是不可变的。 The class that inherits State can then access these parameters through widget.finalMemberVariable .然后继承State的类可以通过widget.finalMemberVariable访问这些参数。 The idea behind this is that every time a new build in the enclosing widget is done, a new StatefulWidget is created, but the associated State is probably persistent across builds.这背后的想法是,每次完成封闭小部件中的新构建时,都会创建一个新的StatefulWidget ,但关联的状State可能在构建中是持久的。 You should never be trying to pull information from things down the widget tree, unless you use GlobalKeys , but they don't really apply when you're using different pages and a navigator.除非您使用GlobalKeys ,否则您永远不应该尝试从小部件树中提取信息,但是当您使用不同的页面和导航器时,它们并不真正适用。

Also, if you just read your code you'll see that mapLength is set to 0 and is not changed until the build function - when you're calling return new _MyMapState().mapLength;此外,如果您只是阅读代码,您会看到 mapLength 设置为 0,并且在构建函数之前不会更改 - 当您调用return new _MyMapState().mapLength; you're creating a new State which has not built yet, and so of course the map length is 0.您正在创建一个尚未建立的新州,因此地图长度当然是 0。

It's not 100% clear what you're trying to do here, but I'll take a guess.目前还不是 100% 清楚你想在这里做什么,但我会猜测一下。 You have a home page with a contacts button.您有一个带有联系人按钮的主页。 When a user taps on it, they get taken to the contacts page where they can remove contacts.当用户点击它时,他们会被带到联系人页面,在那里他们可以删除联系人。 When you get back to the main page, you want to get the number of contacts the user still has.当您返回主页时,您想要获取用户仍然拥有的联系人数量。

First off, I'd suggest using a database or something persistent to store the contacts.首先,我建议使用数据库或持久性的东西来存储联系人。 That way you can add/remove/edit them and they will persist past the app closing.这样您就可以添加/删除/编辑它们,它们将在应用程序关闭后持续存在。 And that way you can just use whatever way of accessing the database you create from both the home page and the contacts page - you query for number on the home page and do actual database manipulations on the contacts page.这样,您就可以使用任何方式访问您从主页和联系人页面创建的数据库 - 您在主页上查询号码并在联系人页面上进行实际的数据库操作。 A fairly easy-to-use plugin to use is sqflite , although there other things like Firebase you could use. sqflite是一个相当易于使用的插件,尽管您可以使用其他东西,例如 Firebase。

The other option is that if you only want the number of contacts after they've popped that page, and you don't want your main page to access the number of contacts, you could pass it back when you do the Navigator.pop ie Navigator.pop(context, contact.length) from the State.另一种选择是,如果您只想要他们弹出该页面后的联系人数量,并且您不希望您的主页访问联系人数量,您可以在执行Navigator.pop时将其传回,即Navigator.pop(context, contact.length)来自州。 In your main page, you'd want to save the result of the Navigator.push(...) either using Futures (something like Navigator.push(...).then((result) { setState(() { this.num = result }) }) ) or using async/await.在您的主页中,您希望使用 Futures 保存Navigator.push(...)的结果(类似于Navigator.push(...).then((result) { setState(() { this.num = result }) }) ) 或使用异步/等待。

All in all though, it seems as though you're not quite clear about how to actually use Flutter.总而言之,您似乎不太清楚如何实际使用 Flutter。 I'd advise starting by following some of the tutorials and codelabs on the flutter website before trying to develop your own app as they'll give you a better idea of how to do this kind of stuff.在尝试开发自己的应用程序之前,我建议先学习一些教程和代码实验室,然后再尝试开发自己的应用程序,因为它们会让你更好地了解如何做这类事情。

I'd second what @rmtmckenzie has mentioned, here's your code edited to show how to pass the modified contacts map between the two pages:我第二次提到@rmtmckenzie ,这是您编辑的代码,以显示如何在两个页面之间传递修改后的联系人映射:

main.dart主要.dart

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Map<String, int> _contact = new Map();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Padding(
              padding: new EdgeInsets.all(20.00),
              child: new RaisedButton(
                onPressed: () {
                  print(_contact.length);
                },
                child: new Text("Get length of map"),
              ),
            ),
            new Padding(
              padding: new EdgeInsets.all(20.00),
              child: new RaisedButton(
                onPressed: () {
                  Navigator.push(
                    context,
                    new MaterialPageRoute(builder: (context) => new MyMap()),
                  ).then((contact) {
                    setState(() => _contact = contact);
                  });
                },
                child: new Text("Goto new Page"),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

map.dart地图.dart

class MyMap extends StatefulWidget {
  @override
  _MyMapState createState() => new _MyMapState();
}

class _MyMapState extends State<MyMap> {
  Map<String, int> contact = {
    "AAAA": 1111,
    "BBBB": 2222,
    "CCCC": 3333,
    "DDDD": 4444,
    "EEEE": 5555,
    "FFFF": 6666,
    "GGGG": 7777,
  };

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "My Map",
      home: new Scaffold(
        appBar: new AppBar(title: new Text("My Map")),
        body: new Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new Padding(
                padding: new EdgeInsets.all(20.00),
                child: new RaisedButton(
                  onPressed: () {
                    contact.remove(contact.keys.elementAt(contact.length - 1));
                  },
                  child: new Text("Remove element from map"),
                ),
              ),
              new Padding(
                padding: new EdgeInsets.all(20.00),
                child: new RaisedButton(
                  onPressed: () {
                    Navigator.pop(context, contact);
                  },
                  child: new Text("Go Back"),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

To conclude, I would recommend having a look at flutter_flux or a similar plugin which allows you to manage state throughout your application without having to continuously pass values between pages.最后,我建议您看一下flutter_flux或类似的插件,它允许您在整个应用程序中管理状态,而无需在页面之间连续传递值。 Example applications can be found in the linked repo, or here .示例应用程序可以在链接的存储库中找到,或者在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM