【问题标题】:Flutter Send Data To Other Screen Without NavigatorFlutter 在没有导航器的情况下将数据发送到其他屏幕
【发布时间】:2020-04-22 09:10:42
【问题描述】:

我有疑问如何在没有导航器且仅使用 onChanged 和 streambuilder 的情况下在页面/屏幕之间传递数据。

我想要的是每当用户在第一个小部件的文本字段中写入时,第二个小部件会自动使用来自第一个小部件的新数据进行刷新。

这是我的 first.dart 代码

import 'package:flutter/material.dart';
import 'second.dart';

class First extends StatefulWidget {
  First({Key key}) : super(key: key);

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

class _FirstState extends State<First> {
      final TextEditingController _myTextController =
        new TextEditingController(text: "");


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("Passing Data"),
      ),
      body: Column(
        children: <Widget>[
          Container(
            height: 120.0,
            child: Column(
              children: <Widget>[
                TextField(
                  controller: _myTextController,
                  onChanged: (String value) {
                    // refresh second with new data
                  },
                )
              ]
            )
          ),
          Container(
            height: 120.0,
            child: Second(
              myText: _myTextController.text,
            ),
          )
        ],
      ),
    );
  }
}

这是我的 second.dart 作为从第一个小部件接收数据的第二个小部件。

import 'dart:async';
import 'package:flutter/material.dart';
import 'api_services.dart';

class Second extends StatefulWidget {
  Second({Key key, @required this.myText}) : super(key: key);

  final String myText;

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

class _SecondState extends State<Second> {
  StreamController _dataController;
  loadPosts() async {
    ApiServices.getDetailData(widget.myText).then((res) async {
      _dataController.add(res);
      return res;
    });
  }

  @override
  void initState() {
    _dataController = new StreamController();
    loadPosts();
    super.initState();
    print(widget.myText);
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: _dataController.stream,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasError) {
            return Text(snapshot.error);
          }
          if (snapshot.hasData) {
            return Container();
          }

          if (snapshot.connectionState == ConnectionState.waiting) {
            return Row(
              children: <Widget>[
                Text("Please Write A Text"),
              ],
            );
          } else if (snapshot.connectionState != ConnectionState.active) {
            return CircularProgressIndicator();
          }

          if (!snapshot.hasData &&
              snapshot.connectionState == ConnectionState.done) {
            return Text('No Data');
          } else if(snapshot.hasData && snapshot.connectionState == ConnectionState.done) {
            return Text(widget.myText);
          }
          return null;
        });
  }
}

【问题讨论】:

  • 了解 Redux 或 BLoC
  • @Urma 我对像 redux/bloc/provider 这样的状态管理还很陌生,我只需要简单的状态来更新下一个屏幕。

标签: flutter stream state


【解决方案1】:

您有几个选择。最简单的两个是 - 将文本编辑控制器本身传递给第二个小部件,然后监听它并调用 setState 来更改第二个小部件中的文本。

示例

class Second extends StatefulWidget {
  Second({Key key, @required this.textController}) : super(key: key);

  final TextEditingController textController;

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

class _SecondState extends State<Second> {
// made this private
String _myText;

@override
void initState() {
  _myText = widget.textController.text
  widget.textController.addListener(() {
    setState((){_myText = widget.textController.text});
    );
  });
  super.initState();
}

...

// then in your build method, put this in place of return Text(widget.myText);
return Text(_myText);

选项 2 在您的第一个小部件中侦听控制器并在那里调用 setState。虽然这将重建第一个和第二个小部件,但我认为它不如第一个选项那么高效。

希望有帮助

【讨论】:

  • 以及如何在没有 navigator.of(context) 的情况下将其从第一个屏幕发送到第二个屏幕?因为我只使用 onChanged: (String value) {}
  • 使用我给你的例子,将第一个小部件中的Second( myText: _myTextController.text, ), 更改为Second(textController: _myTextController)
  • 谢谢,我已经了解您使用监听器的解决方案。
猜你喜欢
  • 2022-07-22
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 2020-06-03
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2020-10-10
相关资源
最近更新 更多