Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send data between tabs in Flutter?

Tags:

I've got a Flutter app with 2 tabs: one that manages and receives a continuous flow of data, the other tab displays the data as it comes in.

How do I pass the data from the first tab to the second? Most of the post I see are about passing data between parent and child, not child to child.

Would I use GlobalKey? is there a better option?

This is the main build function:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('some text'),
      bottom: TabBar(
        tabs: tabs,
        controller: _tabController,
      ),
    ),
    body: TabBarView(
      controller: _tabController,
      children: [
        InputManagment(),
        InfiniteListView(),
      ],
    ),
  );
}
like image 574
CrustyWang Avatar asked Jun 18 '19 21:06

CrustyWang


1 Answers

In this case, it is recommended to use InheritedWidget.

The documentation for InheritedWidget is very comprehensive, including a video from the Flutter team.

First of all, you probably want to create a class that holds the data you want to share.

import 'dart:async';

class MyInheritedWidgetData {
  var sharedData;
  int someCount;
  String someMessage;

  final StreamController _streamController = StreamController.broadcast();

  Stream get stream => _streamController.stream;

  Sink get sink => _streamController.sink;
}

I just added a bunch of variables to this class. You can populate it with whatever you want.
Now, you also want to have an InheritedWidget that holds this data class.

class MyInheritedWidget extends InheritedWidget {
  final MyInheritedWidgetData data;

  MyInheritedWidget({
    Key key,
    @required Widget child,
  })  : assert(child != null),
        data = MyInheritedWidgetData(),
        super(key: key, child: child);

  static MyInheritedWidgetData of(BuildContext context) => (context.inheritFromWidgetOfExactType(MyInheritedWidget) as MyInheritedWidget).data;

  @override
  bool updateShouldNotify(MyInheritedWidget old) => false;
}

You need to place this MyInheritedWidget at the top of your widget tree or at least above parent widget you talked about. The following is supposed to illustrate the necessary widget hierarchy.

MyInheritedWidget
 TabBarView
   InputManagment
   InfiniteListView
// in your build function this would be `body: MyInheritedWidget(child: TabBarView(...))`

Now, you can simply access your data class by using MyInheritedWidget.of(context) in any of your child widgets.

You might want to consider using streams to send and listen to the "flow of data" continuously. However, that would also simply be part of the data class. To give you an idea, I included the stream variable in the example data class. You would add data using MyInheritedWidget.of(context).sink.add(..) and supply your stream to a StreamBuilder using MyInheritedWidget.of(context).stream.

These are all just examples to explain what is needed to share data between widgets. You can read through the documentation for more information and more advanced use cases.

like image 166
creativecreatorormaybenot Avatar answered Sep 29 '22 07:09

creativecreatorormaybenot