Desenvolvimento de Interface Reativa com RxDart e RxCommand no Flutter

Objetivo do Projeto

Este projeto tem como finalidade implemenatr uma aplicação Flutter que utiliza RxDart e RxCommand para gerenciar estado de forma reativa. A interface deve incluir três campos de entrada de texto para números e um rótulo que exibe a soma em tempo real. Entradas não numéricas são consideradas como zero. Os valores iniciais dos campos são 1, 2 e 3, respectivamente.

Inicialização do Projeto

Após a instalação do Flutter, crie um novo projeto utilizando o comando:

flutter create meu_app_rx

Abra o diretório do projeto no Android Studio ou em um editor de sua preferência.

Configuração das Dependências

No arquivo pubspec.yaml, adicione as dependências necessárias para RxDart e RxCommand:

dependencies:
  flutter:
    sdk: flutter
  rxdart: ^0.27.0
  rx_command: ^6.0.0

Execute o comando flutter pub get para baixar os pacotes.

Implementação do Modelo de Dados

Crie um arquivo chamado reactive_model.dart na pasta lib com a seguinte estrutura:

import 'package:rx_command/rx_command.dart';
import 'package:rxdart/rxdart.dart';

class ReactiveModel {
  final campo1 = RxCommand.createSync((String texto) => texto, initialLastResult: "1");
  final campo2 = RxCommand.createSync((String texto) => texto, initialLastResult: "2");
  final campo3 = RxCommand.createSync((String texto) => texto, initialLastResult: "3");
  RxCommand<void string=""> total;

  ReactiveModel() {
    int converterParaInteiro(String valor) => int.tryParse(valor) ?? 0;
    total = RxCommand.createFromStream((_) => CombineLatestStream.combine3(
        campo1.startWith(campo1.lastResult),
        campo2.startWith(campo2.lastResult),
        campo3.startWith(campo3.lastResult),
        (String a, String b, String c) {
          int soma = converterParaInteiro(a) + converterParaInteiro(b) + converterParaInteiro(c);
          return soma.toString();
        }));
    total(total.lastResult);
  }
}</void>

Construção da Interface

No arquivo principal main.dart, configure a aplicação Flutter:

import 'package:flutter/material.dart';
import 'package:meu_app_rx/reactive_model.dart';

void main() {
  runApp(Aplicativo());
}

class Aplicativo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Exemplo Reativo',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: PaginaPrincipal(titulo: 'Página de Exemplo'),
    );
  }
}

class PaginaPrincipal extends StatefulWidget {
  final String titulo;
  PaginaPrincipal({Key chave, this.titulo}) : super(key: chave);

  @override
  _PaginaPrincipalState createState() => _PaginaPrincipalState();
}

class _PaginaPrincipalState extends State<paginaprincipal> {
  final modelo = ReactiveModel();
  TextEditingController controlador1;
  TextEditingController controlador2;
  TextEditingController controlador3;

  _PaginaPrincipalState() {
    controlador1 = TextEditingController(text: modelo.campo1.lastResult);
    controlador2 = TextEditingController(text: modelo.campo2.lastResult);
    controlador3 = TextEditingController(text: modelo.campo3.lastResult);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.titulo),
      ),
      body: Center(
        child: Container(
          width: 200,
          child: Table(
              columnWidths: {0: FractionColumnWidth(.3)},
              defaultVerticalAlignment: TableCellVerticalAlignment.middle,
              children: [
                TableRow(children: [
                  Container(),
                  TextField(
                      controller: controlador1,
                      textAlign: TextAlign.center,
                      onChanged: modelo.campo1)
                ]),
                TableRow(children: [
                  Center(child: Text("+")),
                  TextField(
                      controller: controlador2,
                      textAlign: TextAlign.center,
                      onChanged: modelo.campo2)
                ]),
                TableRow(children: [
                  Center(child: Text("+")),
                  TextField(
                      controller: controlador3,
                      textAlign: TextAlign.center,
                      onChanged: modelo.campo3)
                ]),
                TableRow(children: [
                  Center(child: Text("=")),
                  StreamBuilder(
                    stream: modelo.total,
                    builder: (context, snapshot) =>
                        Text(modelo.total.lastResult, textAlign: TextAlign.center),
                  ),
                ]),
              ]),
        ),
      ),
    );
  }
}</paginaprincipal>

Tags: RxDart RxCommand Flutter Dart Programação Reativa

Publicado em 6-10 22:08 por Thomas