6. Flutter: Gerencia de Estado: Streams
Streams são como se fossem fluxos assincronos, fornecem uma sequência assíncrona de dados.

Quais os objetivos de um Stream?
- Streams fornecem uma sequência assíncrona de dados;
- Sequências de dados incluem eventos gerados pelo usuário e leitura de dados de arquivos;
- Você pode processar um stream usando await for ou listen() a partir da API Stream;
- Os streams fornecem uma maneira de responder a erros;
- Existem dois tipos de streams: single subscription(assinatura única) ou broadcast (múltiplas assinaturas);
Iremos começar por um StatefulWidget
, pois toda vez que usamos uma stream, precisamos chamar o dispose()
para retirá-la da memória.
Para iniciar a nossa stream, precisamos criar um controlador:
import 'dart:async';
class Controller {
// criar controlador
final _controller = StreamController();
}
Toda vez que criamos uma stream, precisamos dar o dispose
dela quando sairmos da página:
import 'dart:async';
class Controller {
// criar controlador
final _controller = StreamController();
void dispose() {
_controller.close();
}
}
Criando nosso estado:
class StateManager {
String nome;
StateManager({
this.nome,
});
}
Tipando nossa stream e criando uma ação:
import 'dart:async';
import 'state.dart';
class Controller {
// criar controlador
final _controller = StreamController();
void alterarNome() {}
void dispose() {
_controller.close();
}
}
Criando nossa acesso ao stream com Getters e criando um construtor para setar nosso estado inicial:
import 'dart:async';
import 'state.dart';
class Controller {
// criar controlador
final _controller = StreamController();
// criando um get
Stream get outAtualizarNome => _controller.stream;
Controller() {
// add estado dentro do controller, estado inicial
_controller.add(
StateManager(
nome: "FlutterBRasil",
),
);
}
void alterarNome(String value) {
_controller.add(
StateManager(
nome: value,
),
);
}
void dispose() {
_controller.close();
}
}
Vamos agora instanciar nosso controlador na nossa page e aproveitar e dar dispose():
class _MyAppState extends State {
final Controller _controller = Controller();
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
Text("Nome"),
RaisedButton(
onPressed: () => _controller.alterarNome("BRasil"),
child: Text("Alterar Nome"),
)
],
),
),
);
}
}
Agora, para recuperar os nossos dados, das streams, utilizaremos o StreamBuilder():
class _MyAppState extends State {
final Controller _controller = Controller();
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
StreamBuilder(
stream: _controller.outAtualizarNome,
builder: (_, snapshot) {
return Text("${snapshot.data.nome}");
}
),
RaisedButton(
onPressed: () => _controller.alterarNome(),
child: Text("Alterar Nome"),
)
],
),
),
);
}
}
Pronto, tudo funcionando. Espero que tenham gostado.