📜  Flutter – 在Flutter页面之间共享数据(1)

📅  最后修改于: 2023-12-03 14:41:16.322000             🧑  作者: Mango

Flutter – 在Flutter页面之间共享数据

在开发Flutter应用程序时,经常需要在不同页面之间共享数据。通过以下方法可以在Flutter页面之间共享数据:

1. 将数据作为构造函数参数传递

我们可以将数据作为构造函数参数传递给将要跳转的页面。例如:

class FirstScreen extends StatelessWidget {
  final String message;
  
  FirstScreen({Key key, this.message}) : super(key: key);
  
  // ...
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      home: FirstScreen(message: 'Hello from MyApp'),
      // ...
    );
  }
}

这里,我们在MyApp页面中创建了一个FirstScreen实例,并将message参数设置为“Hello from MyApp”。我们可以在FirstScreen的构造函数中接收该参数。

接下来,在FirstScreen页面中创建一个Text小部件,将消息当作文本显示出来:

class FirstScreen extends StatelessWidget {
  final String message;
  
  FirstScreen({Key key, this.message}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: Text(message),
      ),
    );
  }
}
2. 使用Navigator

Flutter提供了一个Navigator类来管理页面堆栈。它可以帮助我们在页面之间导航,并创建路由。

在此示例中,我们有两个页面-FirstScreenSecondScreen,并且我们想从FirstScreen页面导航到SecondScreen页面:

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Go to Second Screen'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => SecondScreen(),
              ),
            );
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Go back to First Screen'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}
  • 我们在FirstScreen页面中创建了一个RaisedButton,该按钮在按下时将用户导航到SecondScreen页面。
  • Navigator.push()方法将新的路由推送到页面堆栈上。
  • MaterialPageRoute是一个方便的路由类,它在新页面上显示了一个Material风格的路由,这使得我们的应用程序看起来更加一致和全面。
  • SecondScreen页面中的RaisedButton按钮将用户带回FirstScreen页面。 Navigator.pop()方法将最近的路由弹出堆栈。
3. 使用InheritedWidget

InheritedWidget是Flutter提供的一种特殊小部件,它可以方便地共享数据。当我们使用InheritedWidget包装数据时,我们可以在任何子树中使用该数据,而无需显式传递它。

使用InheritedWidget时,我们需要完成以下步骤:

  • 创建一个继承自InheritedWidget的类,并在其中包含共享数据值。InheritedWidget本身是不可变的,因此我们需要使用StatefulWidget来更新它包含的数据。
  • 在此小部件上包装将要使用共享数据的小部件。我们可以使用BuildContextinheritFromWidgetOfExactType()方法来获取共享数据。
  • 在小部件内部使用此共享数据。

以下是一个简单的示例:

class MyInheritedWidget extends InheritedWidget {
  final int data;
  
  MyInheritedWidget({Key key, @required this.data, @required Widget child})
      : super(key: key, child: child);
  
  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) {
    return data != oldWidget.data;
  }
  
  static MyInheritedWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }
}

class MyStatefulWidget extends StatefulWidget {
  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _count = 0;
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('InheritedWidget demo'),
      ),
      body: MyInheritedWidget(
        data: _count,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('You have pressed the button $_count times.'),
              MyTextWidget(),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _count++;
          });
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class MyTextWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final count = MyInheritedWidget.of(context).data;
    return Text('Count value: $count');
  }
}
  • MyInheritedWidget类是继承自InheritedWidget的自定义小部件。在这个小部件上包装了Center小部件,MyTextWidget可以轻松获取其数据。
  • 我们包装了MyInheritedWidget小部件,因此其下的子组件可以轻松访问_count变量。
  • MyTextWidget小部件使用MyInheritedWidget.of(context).data表达式获取数据,其中of()方法返回最近的MyInheritedWidget小部件。

这是在Flutter页面之间共享数据的三种常见方法。根据你的应用程序需求,你可以采用其中任何方法,也可以使用不同的方法结合起来。