RxDart para os menores ... projetos


Ontem, meu bom amigo disse algo como "Estou escrevendo um aplicativo offline simples, não preciso de todos esses fluxos e fluxos". Fiquei surpreso e pensei que outros codificadores pudessem compartilhar esse erro.


Abaixo, literalmente em 50 linhas, mostrarei por um exemplo bem conhecido que a reatividade


a) não se trata de offline / online
b) é muito simples
c) muito bom para simplificar quase qualquer código


Para meus críticos precipitados
que correm para a batalha sem pensar, considerando que o BlocProvider é um provedor , recomendo que o desenvolvimento geral leia primeiro o artigo básico , cujo link está na página flutter_bloc, na primeira linha da descrição.


O conhecido exemplo "Contador" gerado ao criar um projeto Flutter é menino chicoteado Um bom ponto de partida para demonstrar muitas práticas.
Portanto, ele contém MyHomePage extends StatefulWidget , o método _incrementCounter para o comando increment e setState para redesenhar toda a hierarquia do widget.


Introduzimos a reatividade usando a biblioteca rxdart e algumas etapas simples:


Adicione a biblioteca a pubspec.yaml


 dependencies: ... rxdart: 0.22.2 

Alterar a arquitetura do contador e adicionar evento


 class _Counter { int _count; int get count => _count; _Counter(this._count) : this.onCounterUpd = BehaviorSubject<int>.seeded(_count); ///  . final BehaviorSubject<int> onCounterUpd; ///     ,   . Future incrementCounter() async { onCounterUpd.add(++_count); } } final _counter = _Counter(5); 

Vamos fazer a classe StatelessWidget


 ///   " " class MyHomeRxPage extends StatelessWidget { final title; /// ! -     const MyHomeRxPage({Key key, this.title}) : super(key: key); ... 

Embrulhe o widget de exibição no StreamBuilder e altere a chamada para o método de incremento


  StreamBuilder<int>( stream: _counter.onCounterUpd, builder: (context, snapshot) { return Text( '${snapshot.data}', style: Theme.of(context).textTheme.display1, ); }), ... floatingActionButton: FloatingActionButton( onPressed: _counter.incrementCounter, ... 

Isso é tudo. Parece totalmente com isso


 import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:rxdart/rxdart.dart'; class _Counter { int _count; int get count => _count; _Counter(this._count) : this.onCounterUpd = BehaviorSubject<int>.seeded(_count); ///  . final BehaviorSubject<int> onCounterUpd; ///     ,   . Future incrementCounter() async { onCounterUpd.add(++_count); } } final _counter = _Counter(5); /// class MyHomeRxPage extends StatelessWidget { final title; /// ! -     const MyHomeRxPage({Key key, this.title}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( // Here we take the value from the MyHomePage object that was created by // the App.build method, and use it to set our appbar title. title: Text(title), ), body: Center( // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. child: Column( // Column is also a layout widget. It takes a list of children and // arranges them vertically. By default, it sizes itself to fit its // children horizontally, and tries to be as tall as its parent. // // Invoke "debug painting" (press "p" in the console, choose the // "Toggle Debug Paint" action from the Flutter Inspector in Android // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) // to see the wireframe for each widget. // // Column has various properties to control how it sizes itself and // how it positions its children. Here we use mainAxisAlignment to // center the children vertically; the main axis here is the vertical // axis because Columns are vertical (the cross axis would be // horizontal). mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ StreamBuilder<int>( stream: _counter.onCounterUpd, builder: (context, snapshot) { return Text( 'You have pushed the button ${snapshot.data} times:', ); }), // Text( // 'You have pushed the button this many times:', // ), /// 6. StreamBuilder<int>( stream: _counter.onCounterUpd, builder: (context, snapshot) { return Text( '${snapshot.data}', style: Theme.of(context).textTheme.display1, ); }), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _counter.incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } } 

Agora, o código é reativo, conciso, livre de redesenhos desnecessários e facilmente extensível.
Por exemplo, se no momento da alteração do contador você precisar alterar o texto de outro widget, faça o seguinte:


  StreamBuilder<int>( stream: onCounterUpd, builder: (context, snapshot) { return Text( 'You have pushed the button ${snapshot.data} times:', ); }), // Text( // 'You have pushed the button this many times:', // ), 

e pronto!


Para comparação, tente fazer o mesmo com InheritedWidget, ou outro padrão.


Então, espero mostrar que


  • A reatividade é muito simples. Muito mais fácil InheritedWidgets , BlocProvider , etc.
  • Reatividade não é offline / online. Ela é sobre arquitetura. Como mostrei, nos casos mais simples, você nem precisa adicionar classes adicionais para aplicá-lo.
  • A reatividade é UIs responsivas, extensão rápida de funcionalidade, separação graciosa de código em camadas de qualquer tipo: MVC, MVP, MVI, MVVM, o que você quiser.

Código de exemplo (ramo iter_0004_rxdart )


Editado uma hora depois
Em vão, foi muito simples, obteve cliques para "variáveis ​​globais" e um entendimento errado da inicialização de BehaviorSubject , corrigido

Source: https://habr.com/ru/post/pt474968/


All Articles