Mobile

3 nov, 2020

Flutter e GetX — Criando uma aplicação de compartilhamento de vídeos (Parte 2)

100 visualizações
Publicidade
Image for post

OBJETIVOS

Nesse tutorial vamos continuar a aplicação iniciada aqui.

Iremos implementar os controles e as interfaces do módulo home do aplicativo que desenvolvi no começo da pandemia para ajudar professores e alunos com os vídeos tutoriais sobre o Google ClassRoom.

MÓDULO HOME

Na pasta home vamos criar 3 arquivos e nomeá-los conforme figura 1.

Image for post

Figura 1 — Arquivos do Módulo Home

Ao usar a biblioteca GetX estou arquitetando a aplicação conforme a indicação da documentação e também a estrutura sugerida por https://kauemurakami.github.io/getx_pattern/#home.

Assim, para cada módulo temos um arquivo que representa um Binding, isto é, permite desacoplar a injeção de dependências, realizando uma conexão entre as rotas e a a dependência.

No arquivo home_bind.dart vamos codificar assim:

import 'package:course_app/repositories/recurso_api.dart';
import 'package:get/get.dart';

import 'home_controllerg.dart';

class HomeBind extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<HomeControllerG>(() {
      final RecursoAPI api = RecursoAPI();
      return HomeControllerG(api);
    });
  }
}

Ao herdarmos HomeBind da classe Bindigs devemos sobrescrever o método dependencies(). Na sua implementação utilizamos o método estático lazyPut tipando para o controlador <HomeControllerG>, ainda não implementado.

Observe que instanciamos o repositório da parte 1 em api = RecursoAPI() e em seguida, retornamos no construtor do controlador em HomeControllerG(api)

Não se preocupe com os erros que surgirão na IDE, já que a classe HomeControllerG ainda não foi codificada, o que faremos a seguir.

Home Controller

Vamos iniciar a escrita do controller no arquivo home_controllerg.dart No início temos:

\\ Imports omitidos
class HomeControllerG extends GetxController {
  final categories = List<Categoria>().obs;
  final recursos = List<Recurso>().obs;
  final recursosFiltro = List<Recurso>().obs;

  RxString tipo = ''.obs;
  var qtdAluno = 0.obs;
  var qtdProfessor = 0.obs;
  var qtdPlayList = 0.obs;
  var qtdAtividade = 0.obs;
  var qtdEquipe = 0.obs;
  var qtdProblema = 0.obs;
  var query = "".obs;

  final RecursoAPI api;
  HomeControllerG(this.api);

 

Após os imports, nomeamos a classe como HomeControllerG herdando de GetxController.

Temos a declaração de 3 listas que apresentarão as categorias, os recursos e os filtros.

O detalhe aqui é .obs no final de cada declaração. Apenas com esse acréscimo, estamos transformando em variáveis reativas, permitindo que a aplicação “observa” o estado das listas, atualizando apenas o componente necessário que refletirá os valores.

Na sequência temos a mesma ideia para as variáveis que serão os contadores de recursos por categorias.

Definimos também o construtor para receber a api em

HomeControllerG(this.api);

Continuando, temos a implementação dos métodos que serão executados na inicialização do controlador.

@override
  void onInit() {
    getQtdRecursos();
    super.onInit();
  }

  filtrarTipo() async {
    recursos.value = await api.getRecursos();
    recursos.value =
        recursos.where((element) => element.publico == query.value).toList();
  }

 

O método onInit() é carregado na inicialização, chamando a função que carrega os totalizadores. No exemplo acima eu totaliza a quantidade de recursos por público e professor.

Basicamente é um filtro na lista retornadopela API com where comparando com o atributo público em element.publico == ‘nome da categoria que eu quero’.

Temos ainda o método search que realiza o filtro com base na variável (um campo de interface) .

Future<List<Recurso>> search(String search) async {
    recursosFiltro.value = recursos
        .where((element) =>
            element.titulo.toLowerCase().contains(search.toLowerCase()))
        .toList();
    return Future.delayed(Duration(milliseconds: 800)).then((value) {
      return recursosFiltro.value;
    });
  }

 

O método .contains irá buscar ocorrências do que foi digitado na busca com os valores do títulos dos recursos.

E para finalizar um método que filtra por tipo.

filtrarTipo() async {
    recursos.value = await api.getRecursos();
    recursos.value =
        recursos.where((element) => element.publico == query.value).toList();
  }

 

HomePage

A seguir vou comentar os aspectos na classe responsável pela interface gráfica da home, no arquivo home_page.dart .

class HomePage extends StatelessWidget {
  final HomeControllerG controller = Get.find();

 

Observe que a classe HomePage herda de um StatelessWidget já que com o Get não precisamos mais usar StatefulWidget. Logo abaixo recuperamos o contrloller com o método estático .find()

Image for post

Para observar uma variável utilizando o Get precisamos do widget Obx(). Note que recuperamos a lista de recursos em controller.recursos.value.

Enquanto a lista está sendo carregada, nula ou vazia, exibimos um CircularProgressIndicator.

Abaixo fiz uma mapeamento dos widgtes na Home para facilitar o entendimento.

O código completo da home page está aqui.