翩翩将数据发送到其他屏幕,而不需要导航仪。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了翩翩将数据发送到其他屏幕,而不需要导航仪。相关的知识,希望对你有一定的参考价值。

我有一个问题,如何在flutter的页面屏幕之间传递数据,而不使用导航器,只使用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作为第二个widget从第一个widget接收数据。

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;
        });
  }
}

答案

你有几个选择。最简单的两个选择是--将文本编辑控制器本身传递给第二个小组件,然后监听它并调用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。不过这将会重建第一个和第二个widget,而且我认为性能不如第一个选项。

希望能帮到你

以上是关于翩翩将数据发送到其他屏幕,而不需要导航仪。的主要内容,如果未能解决你的问题,请参考以下文章

导航后未附加回收站视图

无法移动到嵌套子导航组件中的父片段?

在 FAB 单击时导航到片段(导航架构组件)

异步任务片段背景数据

导航到另一个片段时触发 API 调用

如何在底部导航中使用设置屏幕外页面限制