What is the equivalent of Android LiveData in Flutter?

For people interested in an equivalent of LiveData for other scenarios, I present you StreamController:

class ExampleViewModel {

  StreamController<bool> loggedInStream = StreamController<bool>();

  logIn() { loggedInStream.add(true); }
}


class ExampleScreen extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => ExampleScreenState();
}

class ExampleScreenState extends State<ExampleScreen> {

  ExampleViewModel _viewModel;
  BuildContext _ctx;

  @override
  void initState() {
    super.initState();

    _viewModel = ExampleViewModel()
    _viewModel.loggedInStream.stream.listen( (loggedIn) {
      if ( loggedIn != null && loggedIn ) {
        Navigator.of(_ctx).pushReplacementNamed("/home");
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    _ctx = context;

    var loginBtn =
    RaisedButton(
      onPressed: _viewModel.logIn(true),
        child: Text(
          "LOGIN",
          style: new TextStyle(
          fontSize: 24.0,
        )
      ),
      color: Colors.green,
      textColor: Colors.white,
    );

    return loginBtn;
  }

  @override
  void dispose() {
    super.dispose();
    _viewModel.loggedInStream.close();
  }

}

You can subscribe to it just like a LiveData, using:

loggedInStream.stream.listen( (data) { code } )

And you should clear the listeners in dispose to avoid memory leaks:

loggedInStream.close()

This code basically do the following things:

  1. Creates a screen with a button.
  2. Listen to a Stream (observe a LiveData).
  3. When you click the button, it changes the value.
  4. The listener (observer) is triggered.
  5. Launches new screen.

You can use WidgetsBindingObserver to listen to the application state.

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

  @override
  _AppLifecycleReactorState createState() => new _AppLifecycleReactorState();
}

class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  AppLifecycleState _notification;

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() { _notification = state; });
  }

  @override
  Widget build(BuildContext context) {
    return new Text('Last notification: $_notification');
  }
}