· 5 years ago · Nov 25, 2020, 04:26 PM
1import 'package:flutter/material.dart';
2import 'package:flutter/widgets.dart';
3import 'controls/apiClient.dart';
4import 'controls/databaseClient.dart';
5import 'models/dog.dart';
6
7void main() => runApp(MyApp());
8
9class MyApp extends StatelessWidget {
10 @override
11 Widget build(BuildContext context) {
12 return MaterialApp(
13 theme: ThemeData(
14 primarySwatch: Colors.cyan,
15 ),
16 home: DogPage(),
17 );
18 }
19}
20
21class DogPage extends StatefulWidget {
22 @override
23 _DogPageState createState() => _DogPageState();
24}
25
26class _DogPageState extends State<DogPage> {
27 final GlobalKey<FormState> _formStateKey = GlobalKey<FormState>();
28
29 final _scaffoldKey = GlobalKey<ScaffoldState>();
30
31 Future<List<Dog>> dogs;
32
33 List<Dog> dogsFromApi;
34 List<Dog> dogsFromDb;
35
36 String _dogId;
37 String _dogName;
38 int _dogAge;
39
40 bool isUpdate = false;
41
42 String dogIdForUpdate;
43
44 DatabaseClient db;
45
46 ApiClient api;
47
48 final _dogIdController = TextEditingController();
49 final _dogNameController = TextEditingController();
50 final _dogAgeController = TextEditingController();
51
52 @override
53 void initState() {
54 super.initState();
55 db = DatabaseClient();
56 api = ApiClient();
57 openDatabase();
58 }
59
60 openDatabase() async {
61 await db.open();
62 await refreshDogList();
63 }
64
65 refreshDogList() {
66 setState(() {
67 dogs = db.getDogs();
68 });
69 }
70
71 Future<Dog> uploadOnApi(dog) async {
72 try {
73 Dog newDog = await api.insertDog(dog);
74
75 final snackBar = SnackBar(
76 content: Text('Dados enviados com sucesso para a API!'),
77 duration: Duration(milliseconds: 500),
78 backgroundColor: Colors.green,
79 );
80
81 _scaffoldKey.currentState.showSnackBar(snackBar);
82
83 return newDog;
84 }
85 catch (error) {
86 final snackBar = SnackBar(
87 content: Text('Erro ao enviar dado para a API!'),
88 duration: Duration(milliseconds: 500),
89 backgroundColor: Colors.red,
90 );
91 _scaffoldKey.currentState.showSnackBar(snackBar);
92
93 return null;
94 }
95 }
96
97 uploadOnDb(dog) async {
98 try {
99 await db.insertDog(dog);
100 final snackBar = SnackBar(
101 content: Text('Dados enviados com sucesso para a BD!'),
102 duration: Duration(milliseconds: 500),
103 backgroundColor: Colors.green,
104 );
105 _scaffoldKey.currentState.showSnackBar(snackBar);
106 }
107 catch (error) {
108 final snackBar = SnackBar(
109 content: Text('Erro ao enviar dado para o BD!'),
110 duration: Duration(milliseconds: 500),
111 backgroundColor: Colors.red,
112 );
113 _scaffoldKey.currentState.showSnackBar(snackBar);
114 }
115 }
116
117 deleteOnApi(Dog dog) async {
118 try {
119 await api.deleteDog(dog.id);
120 final snackBar = SnackBar(
121 content: Text('Dado removido com sucesso da API!'),
122 duration: Duration(milliseconds: 500),
123 backgroundColor: Colors.green,
124 );
125 _scaffoldKey.currentState.showSnackBar(snackBar);
126 }
127 catch (error) {
128 final snackBar = SnackBar(
129 content: Text('Erro ao remover dado da API!'),
130 duration: Duration(milliseconds: 500),
131 backgroundColor: Colors.red,
132 );
133 _scaffoldKey.currentState.showSnackBar(snackBar);
134 }
135 }
136
137 deleteOnDb(Dog dog) async {
138 try {
139 await db.deleteDog(dog.id);
140 final snackBar = SnackBar(
141 content: Text('Dado removido com sucesso do BD!'),
142 duration: Duration(milliseconds: 500),
143 backgroundColor: Colors.green,
144 );
145 _scaffoldKey.currentState.showSnackBar(snackBar);
146 }
147 catch (error) {
148 final snackBar = SnackBar(
149 content: Text('Erro ao remover dado do BD!'),
150 duration: Duration(milliseconds: 500),
151 backgroundColor: Colors.red,
152 );
153 _scaffoldKey.currentState.showSnackBar(snackBar);
154 }
155 }
156
157 updateOnApi(Dog dog) async {
158 try {
159 await api.updateDog(dog);
160 final snackBar = SnackBar(
161 content: Text('Dado atualizado com sucesso da API!'),
162 duration: Duration(milliseconds: 500),
163 backgroundColor: Colors.green,
164 );
165 _scaffoldKey.currentState.showSnackBar(snackBar);
166 }
167 catch (error) {
168 final snackBar = SnackBar(
169 content: Text('Erro ao atualizar dado na API!'),
170 duration: Duration(milliseconds: 500),
171 backgroundColor: Colors.red,
172 );
173 _scaffoldKey.currentState.showSnackBar(snackBar);
174 }
175 }
176
177 updateOnDb(Dog dog) async {
178 try {
179 await db.updateDog(dog);
180 final snackBar = SnackBar(
181 content: Text('Dado atualizado com sucesso do BD!'),
182 duration: Duration(milliseconds: 500),
183 backgroundColor: Colors.green,
184 );
185 _scaffoldKey.currentState.showSnackBar(snackBar);
186 }
187 catch (error) {
188 final snackBar = SnackBar(
189 content: Text('Erro ao atualizar dado no BD!'),
190 duration: Duration(milliseconds: 500),
191 backgroundColor: Colors.red,
192 );
193 _scaffoldKey.currentState.showSnackBar(snackBar);
194 }
195 }
196
197 downloadFromApi() async {
198 var errorDownload = false;
199
200 try {
201 dogsFromApi = await api.getDogs();
202
203 final snackBar = SnackBar(
204 content: Text('Dados lidos com sucesso na API!'),
205 duration: Duration(milliseconds: 500),
206 backgroundColor: Colors.green,
207 );
208 _scaffoldKey.currentState.showSnackBar(snackBar);
209 }
210 catch (erro) {
211 errorDownload = true;
212
213 final snackBar = SnackBar(
214 content: Text('Erro ao comunicar com a API!'),
215 duration: Duration(milliseconds: 500),
216 backgroundColor: Colors.red,
217 );
218 _scaffoldKey.currentState.showSnackBar(snackBar);
219 }
220
221 if (errorDownload == false) {
222 await db.deleteAllDogs();
223 await db.insertDogs(dogsFromApi);
224 refreshDogList();
225
226 final snackBar = SnackBar(
227 content: Text('Dados armazenados com sucesso no BD!'),
228 duration: Duration(milliseconds: 500),
229 backgroundColor: Colors.green,
230 );
231 _scaffoldKey.currentState.showSnackBar(snackBar);
232 }
233 }
234
235 @override
236 Widget build(BuildContext context) {
237 return Scaffold(
238 key: _scaffoldKey,
239 appBar: AppBar(title: Text('App Dog'), actions: <Widget>[
240 Padding(
241 padding: EdgeInsets.only(right: 20.0),
242 child: GestureDetector(
243 onTap: () {
244 downloadFromApi();
245 },
246 child: Icon(Icons.cloud_download),
247 )),
248 ]),
249
250 body: Column(
251 children: <Widget>[
252 Form(
253 key: _formStateKey,
254 autovalidate: true,
255 child: Column(
256 children: <Widget>[
257 Padding(
258 padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
259 child: TextFormField(
260 enabled: false,
261 onSaved: (value) {
262 _dogId = value;
263 },
264 controller: _dogIdController,
265 keyboardType: TextInputType.number,
266 decoration: InputDecoration(
267 disabledBorder: new UnderlineInputBorder(
268 borderSide: new BorderSide(
269 color: Colors.grey,
270 width: 2,
271 style: BorderStyle.solid)),
272 labelText: "Id do cachorro",
273 icon: Icon(
274 Icons.vpn_key,
275 color: Colors.grey,
276 ),
277 fillColor: Colors.white,
278 labelStyle: TextStyle(
279 color: Colors.grey,
280 )),
281 ),
282 ),
283
284 Padding(
285 padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
286 child: TextFormField(
287 validator: (value) {
288 if (value.isEmpty) {
289 return 'Por favor insira o nome do cachorro';
290 }
291 if (value.trim() == "")
292 return "Somente espaço não é válido!";
293 return null;
294 },
295 onSaved: (value) {
296 _dogName = value;
297 },
298 controller: _dogNameController,
299 decoration: InputDecoration(
300 focusedBorder: new UnderlineInputBorder(
301 borderSide: new BorderSide(
302 color: Colors.cyan,
303 width: 2,
304 style: BorderStyle.solid)),
305 labelText: "Nome do cachorro",
306 icon: Icon(
307 Icons.pets,
308 color: Colors.cyan,
309 ),
310 fillColor: Colors.white,
311 labelStyle: TextStyle(
312 color: Colors.cyan,
313 )),
314 ),
315 ),
316
317 Padding(
318 padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
319 child: TextFormField(
320 validator: (value) {
321 if (value.isEmpty) {
322 return 'Por favor insira a idade do cachorro';
323 }
324 if (value.trim() == "")
325 return "Somente espaço não é válido!";
326 return null;
327 },
328 onSaved: (value) {
329 _dogAge = int.parse(value);
330 },
331 controller: _dogAgeController,
332 keyboardType: TextInputType.number,
333 decoration: InputDecoration(
334 focusedBorder: new UnderlineInputBorder(
335 borderSide: new BorderSide(
336 color: Colors.cyan,
337 width: 2,
338 style: BorderStyle.solid)),
339 labelText: "Idade do cachorro",
340 icon: Icon(
341 Icons.calendar_today,
342 color: Colors.cyan,
343 ),
344 fillColor: Colors.white,
345 labelStyle: TextStyle(
346 color: Colors.cyan,
347 )),
348 ),
349 ),
350 ],
351 ),
352 ),
353
354 Row(
355 mainAxisAlignment: MainAxisAlignment.center,
356 children: <Widget>[
357 RaisedButton(
358 color: Colors.cyan,
359 child: Text(
360 (isUpdate ? 'ATUALIZAR' : 'ADICIONAR'),
361 style: TextStyle(color: Colors.white),
362 ),
363 onPressed: () {
364 FocusScope.of(context).requestFocus(new FocusNode());
365
366 if (isUpdate) {
367 if (_formStateKey.currentState.validate()) {
368 _formStateKey.currentState.save();
369 try {
370 Dog dog = Dog(
371 id: dogIdForUpdate, name: _dogName, age: _dogAge);
372 setState(() {
373 updateOnApi(dog);
374 updateOnDb(dog);
375 refreshDogList();
376 setState(() {
377 isUpdate = false;
378 });
379 });
380 }
381 catch (error) {
382 final snackBar = SnackBar(
383 content: Text('Erro ao comunicar com a API!'),
384 duration: Duration(milliseconds: 500),
385 backgroundColor: Colors.red,
386 );
387 _scaffoldKey.currentState.showSnackBar(snackBar);
388 }
389 }
390 }
391 else {
392 if (_formStateKey.currentState.validate()) {
393 _formStateKey.currentState.save();
394 try {
395 setState(() async {
396 Dog dog =
397 Dog(id: _dogId, name: _dogName, age: _dogAge);
398 await uploadOnDb(await uploadOnApi(dog));
399
400 refreshDogList();
401 });
402 }
403 catch (error) {
404 final snackBar = SnackBar(
405 content: Text('Erro ao comunicar com a API!'),
406 duration: Duration(milliseconds: 500),
407 backgroundColor: Colors.red,
408 );
409 _scaffoldKey.currentState.showSnackBar(snackBar);
410 }
411 }
412 }
413 _dogIdController.text = '';
414 _dogNameController.text = '';
415 _dogAgeController.text = '';
416 },
417 ),
418 Padding(
419 padding: EdgeInsets.all(10),
420 ),
421 RaisedButton(
422 color: Colors.red,
423 child: Text(
424 (isUpdate ? 'CANCELAR ATUALIZAÇÃO' : 'LIMPAR'),
425 style: TextStyle(color: Colors.white),
426 ),
427 onPressed: () {
428 _dogIdController.text = '';
429 _dogNameController.text = '';
430 _dogAgeController.text = '';
431
432 setState(() {
433 isUpdate = false;
434 dogIdForUpdate = null;
435 });
436 },
437 ),
438 ],
439 ),
440 const Divider(
441 height: 20.0,
442 ),
443 Expanded(
444 child: FutureBuilder(
445 future: dogs,
446 builder: (context, snapshot) {
447 print(snapshot.connectionState);
448 if (snapshot.data == null || snapshot.data.length == 0) {
449 return Text('Sem dados para exibir');
450 }
451 else if (snapshot.hasData) {
452 return generateList(snapshot.data);
453 }
454 return CircularProgressIndicator();
455 },
456 ),
457 ),
458 ],
459 ),
460 );
461 }
462
463 SingleChildScrollView generateList(List<Dog> dogs) {
464 return SingleChildScrollView(
465 scrollDirection: Axis.vertical,
466 child: SizedBox(
467 width: MediaQuery.of(context).size.width,
468
469 child: DataTable(
470 columns: [
471 DataColumn(
472 label: Text('ID'),
473 ),
474 DataColumn(
475 label: Text('NOME'),
476 ),
477 DataColumn(
478 label: Text('IDADE'),
479 ),
480 DataColumn(
481 label: Text('DELETAR'),
482 )
483 ],
484 rows: dogs
485 .map(
486 (dog) => DataRow(
487 cells: [
488 DataCell(
489 Text(dog.id.toString()),
490 onTap: () {
491 setState(() {
492 isUpdate = true;
493 dogIdForUpdate = dog.id;
494 });
495 _dogIdController.text = dog.id.toString();
496 _dogNameController.text = dog.name;
497 _dogAgeController.text = dog.age.toString();
498 },
499 ),
500 DataCell(
501 Text(dog.name),
502 onTap: () {
503 setState(() {
504 isUpdate = true;
505 dogIdForUpdate = dog.id;
506 });
507 _dogIdController.text = dog.id.toString();
508 _dogNameController.text = dog.name;
509 _dogAgeController.text = dog.age.toString();
510 },
511 ),
512 DataCell(
513 Text(dog.age.toString()),
514 onTap: () {
515 setState(() {
516 isUpdate = true;
517 dogIdForUpdate = dog.id;
518 });
519 _dogIdController.text = dog.id.toString();
520 _dogNameController.text = dog.name;
521 _dogAgeController.text = dog.age.toString();
522 },
523 ),
524 DataCell(
525 IconButton(
526 icon: Icon(Icons.delete),
527 onPressed: () {
528 try {
529 deleteOnApi(dog);
530 deleteOnDb(dog);
531 refreshDogList();
532 }
533 catch (error) {
534 final snackBar = SnackBar(
535 content: Text('Erro ao comunicar com a API!'),
536 duration: Duration(milliseconds: 500),
537 backgroundColor: Colors.red,
538 );
539 _scaffoldKey.currentState.showSnackBar(snackBar);
540 }
541 },
542 ),
543 ),
544 ],
545 ),
546 )
547 .toList(),
548 ),
549 ),
550 );
551 }
552}