joaopaulofcc

Untitled

Nov 11th, 2020
792
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/widgets.dart';
  3. import 'controls/databaseClient.dart';
  4. import 'models/dog.dart';
  5.  
  6. void main() => runApp(MyApp());
  7.  
  8. class MyApp extends StatelessWidget {
  9.   @override
  10.   Widget build(BuildContext context) {
  11.     return MaterialApp(
  12.       theme: ThemeData(
  13.         primarySwatch: Colors.cyan,
  14.       ),
  15.       home: DogPage(),
  16.     );
  17.   }
  18. }
  19.  
  20. class DogPage extends StatefulWidget {
  21.   @override
  22.   _DogPageState createState() => _DogPageState();
  23. }
  24.  
  25. class _DogPageState extends State<DogPage> {
  26.   // Isso identificará de forma exclusiva o formulário com o qual estamos
  27.   // trabalhando e nos permitirá validar o formulário posteriormente
  28.   final GlobalKey<FormState> _formStateKey = GlobalKey<FormState>();
  29.  
  30.   // Armazenará a lista de cachorros lidos do banco.
  31.   Future<List<Dog>> dogs;
  32.  
  33.   // Armazenarão os dados de um objeto que será manipulado no app (ao criar ou atualizar).
  34.   int _dogId;
  35.   String _dogName;
  36.   int _dogAge;
  37.  
  38.   // Indica se a operação é de update (true) ou insert (false).
  39.   bool isUpdate = false;
  40.  
  41.   // Armazena o id do cachorro que será atualizado em uma operação de update.
  42.   int dogIdForUpdate;
  43.  
  44.   // Armazena a conexão com o banco.
  45.   DatabaseClient db;
  46.  
  47.   // Controladores que vão manipular os textos dos TextEdits.
  48.   final _dogIdController = TextEditingController();
  49.   final _dogNameController = TextEditingController();
  50.   final _dogAgeController = TextEditingController();
  51.  
  52.   // Executada ao inicializar o aplicativo.
  53.   @override
  54.   void initState() {
  55.     super.initState();
  56.     // Cria conexão com o banco.
  57.     db = DatabaseClient();
  58.     // Chama método para abrir o banco.
  59.     openDatabase();
  60.   }
  61.  
  62.   // Método que chama a função open da classe "databaseClient"
  63.   openDatabase() async {
  64.     await db.open();
  65. // Chama método para atualizar a listagem de cachorros já cadastrados no banco.
  66.     refreshDogList();
  67.   }
  68.  
  69.   // Método que atualiza a listagem de cachorros já cadastrados no banco.
  70.   refreshDogList() {
  71.     setState(() {
  72.       dogs = db.getDogs();
  73.     });
  74.   }
  75.  
  76.   // Método que vai construir a interface do app.
  77.   @override
  78.   Widget build(BuildContext context) {
  79.     return Scaffold(
  80.       // Cria AppBar
  81.       appBar: AppBar(
  82.         title: Text('App Dog'),
  83.       ),
  84.  
  85.       // Corpo do app.
  86.       body: Column(
  87.         children: <Widget>[
  88.           // Cria um formulário.
  89.           Form(
  90.             // Atribui a chave para identificar este formulário.
  91.             key: _formStateKey,
  92.             // Indica que a validação dos campos deve ser verificada automaticamente.
  93.             autovalidate: true,
  94.             // Adiciona Padding
  95.             child: Column(
  96.               children: <Widget>[
  97.                 Padding(
  98.                   padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
  99.                   // Adiciona TextForm para inserir o Id do cachorro.
  100.                   child: TextFormField(
  101.                     // Realiza validações de acordo com o valor preenchido.
  102.                     validator: (value) {
  103.                       if (value.isEmpty) {
  104.                         return 'Por favor insira o Id do cachorro';
  105.                       }
  106.                       if (value.trim() == "")
  107.                         return "Somente espaço não é válido!";
  108.                       return null;
  109.                     },
  110.                     // Quando o formulário for enviado, salva o valor preenchido em _dogId.
  111.                     onSaved: (value) {
  112.                       _dogId = int.parse(value);
  113.                     },
  114.                     // Indica quem é o controlador deste TextForm.
  115.                     controller: _dogIdController,
  116.                     // Indica que o teclado padrão deve ser numérico.
  117.                     keyboardType: TextInputType.number,
  118.                     // Personaliza o TextForm
  119.                     decoration: InputDecoration(
  120.                         // Ao ganhar foco cria uma sublinha o TextForm
  121.                         focusedBorder: new UnderlineInputBorder(
  122.                             borderSide: new BorderSide(
  123.                                 color: Colors.cyan,
  124.                                 width: 2,
  125.                                 style: BorderStyle.solid)),
  126.                         // Rótulo do TextForm
  127.                         labelText: "Id do cachorro",
  128.                         // Ícone que será exibido ao lado do TextForm
  129.                         icon: Icon(
  130.                           Icons.vpn_key,
  131.                           color: Colors.cyan,
  132.                         ),
  133.                         // Cor de fundo do TextForm
  134.                         fillColor: Colors.white,
  135.                         // Altera a cor da fonte do rótulo
  136.                         labelStyle: TextStyle(
  137.                           color: Colors.cyan,
  138.                         )),
  139.                   ),
  140.                 ),
  141.  
  142.                 // Repete passos anteriores, porém agora, para o TextForm do nome.
  143.                 Padding(
  144.                   padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
  145.                   child: TextFormField(
  146.                     validator: (value) {
  147.                       if (value.isEmpty) {
  148.                         return 'Por favor insira o nome do cachorro';
  149.                       }
  150.                       if (value.trim() == "")
  151.                         return "Somente espaço não é válido!";
  152.                       return null;
  153.                     },
  154.                     onSaved: (value) {
  155.                       _dogName = value;
  156.                     },
  157.                     controller: _dogNameController,
  158.                     decoration: InputDecoration(
  159.                         focusedBorder: new UnderlineInputBorder(
  160.                             borderSide: new BorderSide(
  161.                                 color: Colors.cyan,
  162.                                 width: 2,
  163.                                 style: BorderStyle.solid)),
  164.                         labelText: "Nome do cachorro",
  165.                         icon: Icon(
  166.                           Icons.pets,
  167.                           color: Colors.cyan,
  168.                         ),
  169.                         fillColor: Colors.white,
  170.                         labelStyle: TextStyle(
  171.                           color: Colors.cyan,
  172.                         )),
  173.                   ),
  174.                 ),
  175.  
  176.                 // Repete passos anteriores, porém agora, para o TextForm da idade.
  177.                 Padding(
  178.                   padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
  179.                   child: TextFormField(
  180.                     validator: (value) {
  181.                       if (value.isEmpty) {
  182.                         return 'Por favor insira a idade do cachorro';
  183.                       }
  184.                       if (value.trim() == "")
  185.                         return "Somente espaço não é válido!";
  186.                       return null;
  187.                     },
  188.                     onSaved: (value) {
  189.                       _dogAge = int.parse(value);
  190.                     },
  191.                     controller: _dogAgeController,
  192.                     keyboardType: TextInputType.number,
  193.                     decoration: InputDecoration(
  194.                         focusedBorder: new UnderlineInputBorder(
  195.                             borderSide: new BorderSide(
  196.                                 color: Colors.cyan,
  197.                                 width: 2,
  198.                                 style: BorderStyle.solid)),
  199.                         labelText: "Idade do cachorro",
  200.                         icon: Icon(
  201.                           Icons.calendar_today,
  202.                           color: Colors.cyan,
  203.                         ),
  204.                         fillColor: Colors.white,
  205.                         labelStyle: TextStyle(
  206.                           color: Colors.cyan,
  207.                         )),
  208.                   ),
  209.                 ),
  210.               ],
  211.             ),
  212.           ),
  213.  
  214.           // Após o fórmulário, organiza na horizontal os botões de ação.
  215.           Row(
  216.             // Centraliza os botões.
  217.             mainAxisAlignment: MainAxisAlignment.center,
  218.             // Adiciona botões.
  219.             children: <Widget>[
  220.               // Botão de dupla função (Atualizar ou Adicionar).
  221.               RaisedButton(
  222.                 color: Colors.cyan,
  223.                 // Se a operação for de atualização mostra "ATUALIZAR", caso
  224.                 // contrário, mostra "ADICIONAR".
  225.                 child: Text(
  226.                   (isUpdate ? 'ATUALIZAR' : 'ADICIONAR'),
  227.                   style: TextStyle(color: Colors.white),
  228.                 ),
  229.                 // Programa função do clique no botão
  230.                 onPressed: () {
  231.                   // Se a operação for de atualização
  232.                   if (isUpdate) {
  233.                     // Verifica se os dados dos TextForms estão válidos.
  234.                     if (_formStateKey.currentState.validate()) {
  235.                       // Se sim, salva os dados nas variáveis.
  236.                       _formStateKey.currentState.save();
  237.                       // E chama o método "updateDog" da classe databaseClient
  238.                       db
  239.                           .updateDog(Dog(
  240.                               id: dogIdForUpdate, name: _dogName, age: _dogAge))
  241.                           .then((data) {
  242.                         // Indica que a operação de atualização já foi realizada,
  243.                         // mudando a variável "isUpdate"
  244.                         setState(() {
  245.                           isUpdate = false;
  246.                         });
  247.                       });
  248.                     }
  249.                   }
  250.                   // Caso a operação a ser executada seja a de inserção de um novo dado.
  251.                   else {
  252.                     // Verifica se os dados dos TextForms estão válidos.
  253.                     if (_formStateKey.currentState.validate()) {
  254.                       // Se sim, salva os dados nas variáveis.
  255.                       _formStateKey.currentState.save();
  256.                       // Chama o método "insertDog" da classe databaseClient
  257.                       db.insertDog(
  258.                           Dog(id: _dogId, name: _dogName, age: _dogAge));
  259.                     }
  260.                   }
  261.                   // Após a atualização ou inserção, limpa os textos dos TextForms
  262.                   _dogIdController.text = '';
  263.                   _dogNameController.text = '';
  264.                   _dogAgeController.text = '';
  265.  
  266.                   // Chama método para recarregar a listagem de cachorros cadastrados.
  267.                   refreshDogList();
  268.                 },
  269.               ),
  270.               Padding(
  271.                 padding: EdgeInsets.all(10),
  272.               ),
  273.               // Botão com dupla função: cancelar a atualização ou limpar os campos
  274.               RaisedButton(
  275.                 color: Colors.red,
  276.                 // Se a operação for de atualização mostra "CANCELAR ATUALIZAÇÃO",
  277.                 // caso contrário, mostra "CANCELAR".
  278.                 child: Text(
  279.                   (isUpdate ? 'CANCELAR ATUALIZAÇÃO' : 'LIMPAR'),
  280.                   style: TextStyle(color: Colors.white),
  281.                 ),
  282.                 // Programa o que ocorrerá quando o botão for clicado
  283.                 onPressed: () {
  284.                   // Em ambas as situações limpa os dados dos TextForms
  285.                   _dogIdController.text = '';
  286.                   _dogNameController.text = '';
  287.                   _dogAgeController.text = '';
  288.  
  289.                   setState(() {
  290.                     // Indica que não está ocorrendo mais uma atualização
  291.                     isUpdate = false;
  292.                     // Limpa a variável que armazenaria o id a ser atualizado
  293.                     dogIdForUpdate = null;
  294.                   });
  295.                 },
  296.               ),
  297.             ],
  298.           ),
  299.           const Divider(
  300.             height: 20.0,
  301.           ),
  302.           // Componente que exibirá a listagem com os cachorros cadastrados.
  303.           Expanded(
  304.             // Para saber +: https://tinyurl.com/y44rl6ce
  305.             child: FutureBuilder(
  306.               future: dogs,
  307.               builder: (context, snapshot) {
  308.                 // Caso não exista dados a serem exibidos, mostra uma mensagem
  309.                 if (snapshot.data == null || snapshot.data.length == 0) {
  310.                   return Text('Sem dados para exibir');
  311.                 }
  312.                 // Se o banco tiver retornado dados para exibir, ou seja, dados
  313.                 // cadastrados, chama método para gerar a lista de cachorros e
  314.                 // e posteriormente exibir tal lista na tela.
  315.                 else if (snapshot.hasData) {
  316.                   return generateList(snapshot.data);
  317.                 }
  318.                 // Retorna um widget circular que será apresentado enquanto a
  319.                 // operação de recuperação de dados estiver sendo processada.
  320.                 return CircularProgressIndicator();
  321.               },
  322.             ),
  323.           ),
  324.         ],
  325.       ),
  326.     );
  327.   }
  328.  
  329.   // Método que retorna um widget com a lista de cachorros cadastrados no banco.
  330.   SingleChildScrollView generateList(List<Dog> dogs) {
  331.     return SingleChildScrollView(
  332.       // Indica a direção de rolagem vertical.
  333.       scrollDirection: Axis.vertical,
  334.       child: SizedBox(
  335.         // A largura da lista será a largura da tela do aparelho
  336.         width: MediaQuery.of(context).size.width,
  337.  
  338.         // Monta DataTable com dados obtidos do banco (recebido aqui como parâmetro)
  339.         // Monta cabeçalho
  340.         child: DataTable(
  341.           columns: [
  342.             DataColumn(
  343.               label: Text('ID'),
  344.             ),
  345.             DataColumn(
  346.               label: Text('NOME'),
  347.             ),
  348.             DataColumn(
  349.               label: Text('IDADE'),
  350.             ),
  351.             DataColumn(
  352.               label: Text('DELETAR'),
  353.             )
  354.           ],
  355.           // Monta linhas
  356.           rows: dogs
  357.               .map(
  358.                 (dog) => DataRow(
  359.                   cells: [
  360.                     // Célula que exibirá o id do cachorro.
  361.                     DataCell(
  362.                       Text(dog.id.toString()),
  363.                       // Quando o usuário clicar nesta célula ativa a operação
  364.                       // de atualização.
  365.                       onTap: () {
  366.                         setState(() {
  367.                           // Indica que a operação de atualização está ativada
  368.                           isUpdate = true;
  369.                           // Salva o id do objeto apresentado na linha selecionada
  370.                           dogIdForUpdate = dog.id;
  371.                         });
  372.                         // Preenche, com os dados do cachorro selecionado, os TextForms
  373.                         _dogIdController.text = dog.id.toString();
  374.                         _dogNameController.text = dog.name;
  375.                         _dogAgeController.text = dog.age.toString();
  376.                       },
  377.                     ),
  378.                     // Célula que exibirá o nome do cachorro.
  379.                     DataCell(
  380.                       Text(dog.name),
  381.                       onTap: () {
  382.                         setState(() {
  383.                           isUpdate = true;
  384.                           dogIdForUpdate = dog.id;
  385.                         });
  386.                         _dogIdController.text = dog.id.toString();
  387.                         _dogNameController.text = dog.name;
  388.                         _dogAgeController.text = dog.age.toString();
  389.                       },
  390.                     ),
  391.                     // Célula que exibirá a idade do cachorro.
  392.                     DataCell(
  393.                       Text(dog.age.toString()),
  394.                       onTap: () {
  395.                         setState(() {
  396.                           isUpdate = true;
  397.                           dogIdForUpdate = dog.id;
  398.                         });
  399.                         _dogIdController.text = dog.id.toString();
  400.                         _dogNameController.text = dog.name;
  401.                         _dogAgeController.text = dog.age.toString();
  402.                       },
  403.                     ),
  404.                     // Célula que exibirá o botão para deletar uma linha do banco
  405.                     DataCell(
  406.                       IconButton(
  407.                         icon: Icon(Icons.delete),
  408.                         // Ao clicar no botão chama o método deleteDog
  409.                         // da classe databaseClient
  410.                         onPressed: () {
  411.                           db.deleteDog(dog.id);
  412.                           refreshDogList();
  413.                         },
  414.                       ),
  415.                     ),
  416.                   ],
  417.                 ),
  418.               )
  419.               .toList(),
  420.         ),
  421.       ),
  422.     );
  423.   }
  424. }
RAW Paste Data