【问题标题】:In Flutter, how do I pass data into a Stateless Widget?在 Flutter 中,如何将数据传递给 Stateless Widget?
【发布时间】:2020-01-21 16:19:18
【问题描述】:

我正在尝试构建我的第一个 Flutter 应用程序,但在将数据传递到无状态小部件时遇到了困难。我有以下课程:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'App Title',
      theme: new ThemeData(
        primarySwatch: Colors.green,
      ),
      home: new MainBody(),
    );
  }
}


class MainBody extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Padding(
        padding: const EdgeInsets.only(left: 20.0, right: 20.0),
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new TimeCheck(),
          ],
        ),
      ),
    );
  }
}

TimeCheck 是一个Stateful Widget。基本上,我希望能够在开始时设置一些值,然后通过MainBody 将它们传递给TimeCheck。我读到的所有内容都显示了如何将数据传递到Stateful Widgets,但是否可以通过Stateless Widget 传递数据?

我知道我可能采取了错误的方法,所以如果有帮助,我最终想做的是有一个“设置”页面,用户可以在其中设置数据的值(字符串和一些数字),然后将这些值传递给TimeCheck,用于生成显示。

如果可能的话,我还希望能够保存用户设置的值,这样他们就不必每次都输入它们,然后我希望能够在TimeCheck 时读取它们被实例化了。

【问题讨论】:

    标签: flutter statelesswidget flutter-widget


    【解决方案1】:

    是的,您只需将信息传递给构造函数即可。像这样的:

     class MyApp extends StatelessWidget {
      MyApp(this.yourData);
    
      final int yourData;
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'App Title',
          theme: new ThemeData(
            primarySwatch: Colors.green,
          ),
          home: new MainBody(yourData),
        );
      }
    }
    
    
    class MainBody extends StatelessWidget {
      MainBody(this.yourData);
    
      final int yourData;
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: new Padding(
            padding: const EdgeInsets.only(left: 20.0, right: 20.0),
            child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new TimeCheck(yourData),
              ],
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 如何将“yourData”变量传递给填充值以代替 20.0? Dart 说它不是一个常数。
    【解决方案2】:

    为此,我们创建了一个StatelessWidget。我们称之为 TodosScreen。由于此页面的内容在运行时不会更改,因此我们必须在此小部件范围内要求待办事项列表。

    我们传入 ListView.builder 作为我们要返回到 build() 的小部件的主体。这会将列表呈现在屏幕上供您开始使用!

    class TodosScreen extends StatelessWidget {
      final List<Todo> todos;
    
      //requiring the list of todos
      TodosScreen({Key key, @required this.todos}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Todos'),
          ),
          //passing in the ListView.builder
          body: ListView.builder(
            itemCount: todos.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(todos[index].title)
              );
            },
          ),
        );
      }
    }
    

    创建一个详细的屏幕来显示有关待办事项的信息

    现在,创建第二个屏幕。屏幕标题包含待办事项的标题,屏幕正文显示描述。

    由于详细信息屏幕是普通的StatelessWidget,因此需要用户在 UI 中输入 Todo。然后,使用给定的待办事项构建 UI。

    class DetailScreen extends StatelessWidget {
      // Declare a field that holds the Todo.
      final Todo todo;
    
      // In the constructor, require a Todo.
      DetailScreen({Key key, @required this.todo}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        // Use the Todo to create the UI.
        return Scaffold(
          appBar: AppBar(
            title: Text(todo.title),
          ),
          body: Padding(
            padding: EdgeInsets.all(16.0),
            child: Text(todo.description),
          ),
        );
      }
    }
    

    导航并将数据传递到详细信息屏幕

    有了DetailScreen,您就可以执行导航了。在此示例中,当用户点击列表中的待办事项时,导航到 DetailScreen。将待办事项传递给 DetailScreen。

    ListView.builder(
      itemCount: todos.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(todos[index].title),
          // When a user taps the ListTile, navigate to the DetailScreen.
          // Notice that you're not only creating a DetailScreen, you're
          // also passing the current todo to it.
          onTap: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => DetailScreen(todo: todos[index]),
              ),
            );
          },
        );
      },
    );
    

    欲了解更多信息,请参阅https://flutter.dev/docs/cookbook/navigation/passing-data

    【讨论】:

    • 如果你想要不可为空(null 安全),你可以使用DetailScreen(this.todo,{Key key}) : super(key: key);DetailScreen({Key key, required this.todo}) : super(key: key);(需要不带@)
    【解决方案3】:

    简单解释:

    class MainMenuCard extends StatelessWidget {
    final Choice choice;
    final int index;
    
    const MainMenuCard({Key key, this.choice, this.index, Choice Choice, int int})
      : super(key: key);
     
    

    然后像这样打电话

    MainMenuCard(choice : choices[index],int: index)
    

    'Choice' 是 Model 类(当我们与 List.generate 一起使用时),否则您可以轻松传递数据。

     final Choice choice;
     const List<Choice> choices = const <Choice>[]
    

    【讨论】:

      猜你喜欢
      • 2020-12-17
      • 2020-02-27
      • 2021-04-24
      • 2021-05-28
      • 1970-01-01
      • 2020-10-17
      • 2021-06-21
      • 1970-01-01
      • 2019-02-27
      相关资源
      最近更新 更多