• Nenhum resultado encontrado

CENTRO UNIVERSITÁRIO DINÂMICA DAS CATARATAS CURSO DE SISTEMAS DE INFORMAÇÃO

N/A
N/A
Protected

Academic year: 2021

Share "CENTRO UNIVERSITÁRIO DINÂMICA DAS CATARATAS CURSO DE SISTEMAS DE INFORMAÇÃO"

Copied!
90
0
0

Texto

(1)

ANÁLISE DOS FRAMEWORKS FLUTTER E REACT NATIVE APLICADO AO DESENVOLVIMENTO MULTIPLATAFORMA DE APLICATIVOS MÓVEIS

JESSÉ DOS SANTOS VICENTE

FOZ DO IGUAÇU - PR 2020

(2)

ANÁLISE DOS FRAMEWORKS FLUTTER E REACT NATIVE APLICADO AO DESENVOLVIMENTO MULTIPLATAFORMA DE APLICATIVOS MÓVEIS

Trabalho de Graduação submetido como requisito da disciplina Trabalho de Graduação II por Jessé dos Santos Vicente, acadêmico do Curso de Graduação de Sistemas de Informação, sob a orientação do professor Dr. Anderson Andrei De Bona. UDC - União Dinâmica de Faculdades Cataratas - Foz do Iguaçu, Paraná.

FOZ DO IGUAÇU - PR 2020

(3)

VICENTE, Jessé dos Santos.

Análise dos Frameworks Flutter e React Native Aplicado ao Desenvolvimento Multiplataforma de Aplicativos Móveis / Jessé dos Santos Vicente – Foz do Iguaçu - 2020.

90 f.

Monografia, (Trabalho de Conclusão do Curso de Sistemas de Informação) - Centro Universitário Dinâmica das Cataratas, 2020.

Orientador: Prof. Dr. Anderson A. De Bona

(4)

Dedico este trabalho a todos que de alguma forma me apoiaram durante todo este trajeto, em especial a Deus, minha família, meus amigos e meus professores.

(5)

Agradeço primeiramente a Deus por ter colocado pessoas tão incríveis na minha vida e por ter permitido que eu chegasse até aqui.

A minha família, que sempre esteve disposta a me apoiar e incentivar para que eu pudesse alcançar os meus objetivos e por ter proporcionado todas as condições necessárias para minha formação educacional.

A minha namorada e amiga Maria Rayane Félix Pacífico, por sempre estar ao meu lado em todos os momentos me ajudando a superar todas as dificuldades encontradas e me incentivando a sempre continuar focado em meus objetivos.

A todos os meus amigos que sempre estiveram comigo e por me mostrarem o significado da verdadeira amizade.

Aos meus professores, especialmente ao meu orientador, Prof. Dr. Anderson A. De Bona, que com excelência me orientou na elaboração desse trabalho acadêmico e ao Prof. Adélio de Souza Conter por seus relevantes comentários e considerações que agregaram muito valor a este trabalho.

(6)

JESSÉ DOS SANTOS VICENTE

ANÁLISE DOS FRAMEWORKS FLUTTER E REACT NATIVE APLICADO AO DESENVOLVIMENTO MULTIPLATAFORMA DE APLICATIVOS MÓVEIS

Trabalho de Conclusão de Curso apresentado ao Centro Universitário Dinâmica das Cataratas UDC, curso de Sistemas de Informação, para obtenção do grau de Bacharel de Sistemas de Informação.

Aprovado pela banca examinadora formada por:

_____________________________________ Orientador: Prof. Dr. Anderson A. De Bona

_____________________________________ Prof. Me. Adélio de Souza Conter

_____________________________________ Prof. Me. Luciano S. Cardoso

FOZ DO IGUAÇU - PR 2020

(7)

de Conclusão de Curso (Graduação em Sistemas de Informação) – Centro Universitário Dinâmica das Cataratas, 2020.

RESUMO

Com os smartphones sendo parte do nosso cotidiano, o uso de aplicativos móveis tem aumentado dia após dia. O desenvolvimento de aplicativos nativos pode ser um processo desafiador, pois, para que o aplicativo funcione tanto em dispositivos Android como iOS, são necessárias duas bases de código diferentes utilizando as linguagens nativas específicas de cada sistema operacional. Consequentemente, isso afeta a produtividade e os custos aumentam, uma vez que as empresas precisam de equipes de desenvolvimento especializadas para cada tipo de sistema operacional. O React Native e Flutter (criados pelo Facebook e Google respectivamente), são frameworks que surgiram como uma solução multiplataforma para auxiliar no desenvolvimento de aplicativos para Android e iOS utilizando apenas uma base de código. Este trabalho teve como objetivo analisar e comparar as principais características desses frameworks. A pesquisa foi baseada em artigos sobre desenvolvimento de aplicativos multiplataforma utilizando React Native e Flutter, onde foi possível identificar como suas arquiteturas técnicas operam nos aplicativos e como as características estudadas se relacionam entre si. Baseado no desenvolvimento de uma prova de conceito, onde foi construído um aplicativo gerenciador de tarefas em cada framework, constatou-se que o React Native proporciona um ambiente de desenvolvimento muito semelhante ao do desenvolvimento web, pois utiliza o JavaScript para a construção de aplicativos. Isso significa que desenvolvedores web, principalmente, podem facilmente construir aplicativos para Android e iOS por meio desta tecnologia. Por outro lado, o Flutter utiliza a linguagem Dart, que é baseada em classes e possui sintaxe semelhante a outras linguagens robustas como o Java e o C#. Este é um fator crucial que reduz a curva de aprendizado e domínio dessa tecnologia para qualquer desenvolvedor que em algum momento tenha programado com uma dessas linguagens.

(8)

(graduation degree in Information Systems) – Centro Universitário Dinâmica das Cataratas, 2020.

ABSTRACT

With smartphones being part of our daily lives, the use of mobile apps has increased day by day. The development of native applications can be a challenge, because, for the application to work on both Android and iOS devices, two different code bases are required using the native languages specific to each operating system. Consequently, this affects productivity and costs are increased, as companies need specialized development teams for each type of operating system. React Native and Flutter (created by Facebook and Google respectively), are frameworks that have emerged as a cross-platform solution to assist in the development of applications for Android and iOS using only a code base. This work aimed to analyze and compare the main characteristics of these frameworks. The research was based on articles on cross-platform application development using React Native and Flutter where it was possible to identify how their technical architectures operate in the applications and how the characteristics studied are related to each other. Based on the development of a proof of concept, where a task manager application was built in each framework, it was found that React Native provides a development environment very similar to web development, as it uses JavaScript to build applications. This means that web developers, in particular, can easily build applications for Android and iOS through this technology. On the other hand, Flutter uses the Dart language, which is based on classes and has a syntax similar to other robust languages such as Java and C#. This is a crucial factor that reduces the learning curve and mastery of this technology for any developer who has ever programmed with one of these languages.

(9)

Figura 1 - Metodologia para execução da pesquisa ... 20

Figura 2 - Desenvolvimento Nativo ... 21

Figura 3 - Frequência de busca dos termos React Native e Flutter ... 23

Figura 4 - Percentual de tópicos sobre frameworks multiplataforma ... 24

Figura 5 - Desenvolvimento Multiplataforma ... 25

Figura 6 - Arquitetura do React Native ... 30

Figura 7 - Como o React calcula as alterações no Virtual DOM ... 31

Figura 8 - Exemplo de declaração de um componente JSX no React JS ... 32

Figura 9 - Utilizando props no React JS ... 33

Figura 10 - Utilizando props no React Native ... 34

Figura 11 - Utilização do state no React Native ... 35

Figura 12 - Componente Text utilizando inline styles ... 36

Figura 13 - Objeto de estilos utilizando Stylesheet ... 37

Figura 14 - Componente View ... 38

Figura 15 - Componente Text utilizando StyleSheet ... 38

Figura 16 - Componente Image utilizando endereço URL ... 39

Figura 17 - Componente TextInput ... 40

Figura 18 - Detectando a plataforma atual no React Native ... 40

Figura 19 - Pilha de rotas StackNavigator ... 41

Figura 20 - React Navigation método navigate ... 42

Figura 21 - Arquitetura do Flutter ... 43

Figura 22 - Função runApp Flutter ... 45

Figura 23 - Widget Container ... 46

Figura 24 - Widget Text ... 47

Figura 25 - Widget Text com TextStyle ... 47

Figura 26 - Widget Row ... 48

Figura 27 - Widget Row com widget Expanded ... 48

Figura 28 - Comportamento widget Row ... 49

Figura 29 - Widget Column... 49

Figura 30 - Comportamento do widget Column ... 50

Figura 31 - Flutter Navigator método push ... 51

(10)

Figura 34 - Hello World no React Native e no Flutter ... 54

Figura 35 - React Native bridge ... 55

Figura 36 - Canais de plataforma ... 56

Figura 37 - Renderização no React Native ... 57

Figura 38 - Renderização no Flutter ... 58

Figura 39 - Diagrama de métodos de ciclo de vida de componentes do React JS ... 59

Figura 40 - Diagrama do ciclo de vida dos widgets no Flutter ... 60

Figura 41 - Diagrama de casos de uso ... 64

Figura 42 - Diagrama entidade relacionamento ... 66

Figura 43 - Tela inicial ... 67

Figura 44 - Tela de cadastro de nova tarefa... 68

Figura 45 - Tela de listagem de tarefas ... 69

Figura 46 - Criando novo projeto no React Native ... 71

Figura 47 - Novo projeto no React Native ... 72

Figura 48 - Estrutura de pastas novo projeto no React Native ... 73

Figura 49 - Estrutura de pastas do aplicativo no React Native ... 74

Figura 50 - Métodos useState e useEffect ... 75

Figura 51 - Pilha de rotas do aplicativo React Native ... 76

Figura 52 - Componente DateTimePicker do React Native ... 77

Figura 53 - React Navigation no React Native ... 77

Figura 54 - Plugins Flutter e Dart para Visual Studio Code ... 78

Figura 55 - Criando novo projeto no Flutter ... 78

Figura 56 - Novo projeto no Flutter ... 79

Figura 57 - Estrutura de pastas novo projeto no Flutter ... 80

Figura 58 - Estrutura de pastas do aplicativo no Flutter ... 81

Figura 59 - Métodos initState e setState ... 82

(11)

Quadro 1 - Comparativo entre desenvolvimento nativo e multiplataforma ... 28

Quadro 2 - Diferenças entre widgets stateful e stateless no Flutter ... 45

Quadro 3 - Métodos de ciclo de Vida no Flutter ... 60

Quadro 4 - Comparativo entre React Native e Flutter ... 62

Quadro 5 - Descrição do caso de uso "Visualizar tela inicial" ... 64

Quadro 6 - Descrição do caso de uso “Adicionar tarefa" ... 65

Quadro 7 - Descrição do caso de uso "Visualizar tarefas" ... 65

(12)

AOT Ahead of Time (Antes do Tempo)

API Application Programming Interface (Interface de Programação de Aplicações) CLI Command Line Interface (Interface de Linha de Comando)

CSS Cascading Style Sheets (Folha de Estilo em Cascata)

GPS Global Positioning System (Sistema de Posicionamento Global)

DOM Document Object Model (Modelo de Objeto de Documento)

ES6 ECMAScript 2015

HTML Hypertext Markup Language (Linguagem de Marcação de Hipertexto) IDE Integrated Development Environment (Ambiente de Desenvolvimento Integrado)

JDK Java Development Kit (Kit de Desenvolvimento Java) JSX JavaScript XML

LLVM Low Level Virtual Machine (Máquina Virtual de Baixo Nível) NDK Native Development Kit (Kit de Desenvolvimento Nativo) PoC Proof of Concept (Prova de Conceito)

SDK Software Development Kit (Kit de Desenvolvimento de Software) UI User Interface (Interface do Usuário)

URL Uniform Resource Locator (Localizador Uniforme de Recursos) VM Virtual Machine (Máquina Virtual)

WORA Write Once, Run Anywhere (Escreva uma vez, execute em qualquer lugar) XML Extensible Markup Language (Linguagem de Marcação Extensível)

(13)

INTRODUÇÃO ... 16 OBJETIVOS ... 16 1.1.1 Objetivo Geral ... 16 1.1.2 Objetivos Específicos ... 17 JUSTIFICATIVA... 17 PROBLEMA ... 17 PROCEDIMENTOS METODOLÓGICOS ... 17 1.4.1 Finalidade ... 18 1.4.2 Abordagem ... 18 1.4.3 Procedimentos ... 18 ESTRUTURA DO TRABALHO ... 20 FUNDAMENTAÇÃO TEÓRICA ... 21 2.1 DESENVOLVIMENTO NATIVO... 21

2.1.1 Vantagens do Desenvolvimento Nativo ... 22

2.1.2 Desvantagens do Desenvolvimento Nativo ... 22

2.2 DESENVOLVIMENTO MULTIPLATAFORMA ... 24

2.2.1 Vantagens do Desenvolvimento Multiplataforma ... 25

2.2.2 Desvantagens do Desenvolvimento Multiplataforma ... 26

2.3 COMPARATIVO DESENVOLVIMENTO NATIVO X MULTIPLATAFORMA . 27 2.4 REACT NATIVE... 28 2.4.1 Arquitetura ... 29 2.4.2 Virtual DOM ... 30 2.4.3 JSX ... 31 2.4.3.1 Props ... 32 2.4.3.2 States ... 34 2.4.4 Componentes Nativos ... 35

2.4.4.1 Estilização em Componentes Nativos ... 35

2.4.4.2 View ... 37

2.4.4.3 Text ... 38

2.4.4.4 Image ... 39

2.4.4.5 TextInput ... 39

(14)

2.5 FLUTTER ... 42 2.5.1 Arquitetura ... 43 2.5.2 Widgets ... 44 2.5.3 Widgets básicos ... 46 2.5.3.1 Container ... 46 2.5.3.2 Text ... 46 2.5.3.3 Row ... 48 2.5.3.4 Column ... 49 2.5.4 Material e Cupertino ... 50 2.5.5 Navegação ... 50 ANÁLISE COMPARATIVA ... 53 3.1 LINGUAGEM DE PROGRAMAÇÃO ... 53

3.2 COMUNICAÇÃO COM O CÓDIGO NATIVO ... 54

3.3 RENDERIZAÇÃO ... 56

3.4 MANIPULAÇÃO DE ESTADO ... 58

3.5 TEMPO DE DESENVOLVIMENTO ... 61

3.6 QUADRO COMPARATIVO ... 62

DESENVOLVIMENTO DA PROVA DE CONCEITO ... 63

4.1 REQUISITOS DO SISTEMA ... 63

4.1.1 Requisitos funcionais ... 63

4.1.2 Requisitos não funcionais ... 63

4.2 DIAGRAMA DE CASOS DE USO ... 64

4.3 DESCRIÇÃO DOS CASOS DE USO ... 64

4.4 DIAGRAMA ENTIDADE RELACIONAMENTO ... 66

4.5 PROTÓTIPOS DE TELAS ... 67

4.5.1 Tela inicial ... 67

4.5.2 Nova tarefa ... 68

4.5.3 Visualizar tarefas ... 69

4.6 CONFIGURAÇÕES DE AMBIENTE ... 70

4.6.1 Ambiente React Native ... 70

4.6.2 Ambiente Flutter ... 70

4.7 APLICATIVO REACT NATIVE ... 71

(15)

2.5.1 States ... 75 4.7.3 Bibliotecas ... 75 4.7.3.1 React Navigation ... 75 4.7.3.2 DateTimePicker ... 76 4.7.3.3 Vector Icons ... 77 4.8 APLICATIVO FLUTTER ... 78

4.8.1 Iniciando novo projeto ... 78

4.8.2 Estrutura de pastas ... 80

4.8.3 States ... 81

2.5.1 Material Design e Navigator ... 82

CONCLUSÃO... 84

5.1 TRABALHOS FUTUROS ... 85

(16)

INTRODUÇÃO

O desenvolvimento de aplicativos móveis tornou-se uma grande área dentro da indústria de desenvolvimento de software. Enquanto isso, usuários ao redor do mundo utilizam dispositivos com diferentes sistemas operacionais. Para atingir o maior número possível de usuários, os desenvolvedores precisam fazer com que seus aplicativos funcionem em diferentes plataformas (CORRAL; JANES; REMENCIUS, 2012).

Empresas como Apple e Google criaram ferramentas que ajudam no desenvolvimento de aplicativos para plataformas iOS e Android respectivamente, dando a possibilidade aos desenvolvedores iOS criarem suas aplicações com a ferramenta Xcode utilizando linguagem Objective-C (DEVELOPER, 2020), e aos desenvolvedores Android com a ferramenta Android Studio utilizando linguagem Java (DEVELOPERS, 2020).

Segundo Wu (2018), para que aplicativos funcionassem tanto em sistemas Android quanto iOS, era necessário que os desenvolvedores tivessem conhecimento sobre dois conjuntos de tecnologias completamente diferentes, o que, consequentemente, tornava o processo de desenvolvimento mais longo, dada a necessidade da criação de uma aplicação específica para cada sistema operacional. A esse respeito, Rodríguez-Sánchez Guerra (2018) descreve que à medida que o número de aplicativos móveis cresce, alternativas de desenvolvimento multiplataforma tendem a serem adotadas, pois permitem ter uma única base de código para implantar o aplicativo em plataformas distintas.

Para Khandozhenko (2014), as soluções multiplataforma atraem aqueles que desejam desenvolver seu produto de forma rápida e barata, simultaneamente e em várias plataformas por um simples motivo - uma única base de código.

OBJETIVOS 1.1.1 Objetivo Geral

Analisar e comparar os frameworks Flutter e React Native no desenvolvimento multiplataforma para dispositivos móveis.

(17)

1.1.2 Objetivos Específicos

• Expor os conceitos do desenvolvimento nativo em dispositivos móveis; • Expor os conceitos do desenvolvimento multiplataforma em dispositivos móveis;

• Apresentar as arquiteturas técnicas dos frameworks React Native e Flutter; • Realizar uma análise comparativa entre o React Native e o Flutter;

• Desenvolver uma PoC (prova de conceito), utilizando React Native e Flutter; • Analisar as principais características do React Native e Flutter, baseado na PoC.

JUSTIFICATIVA

De acordo com El-Kassas et al. (2017), uma das principais dificuldades que os desenvolvedores de aplicativos enfrentaram nos últimos anos, era desenvolver suas aplicações para diferentes sistemas operacionais, como Android e iOS, uma vez que, o processo de desenvolvimento de um aplicativo que execute em ambas, exige conhecimento em um conjunto de tecnologias completamente diferentes.

Buscando resolver este problema, o Facebook introduziu em 2015 o React Native, para desenvolvimento de aplicativos para sistemas iOS e Android de forma nativa utilizando JavaScript (NATIVE, 2020a). Logo depois, a Google, em 2017, passou a promover a sua solução, a qual deram o nome Flutter, que ajuda no desenvolvimento de aplicativos multiplataforma utilizando a linguagem Dart (FLUTTER, 2020a).

De acordo com Wu (2018), as soluções multiplataforma voltadas ao desenvolvimento de aplicativos móveis chamaram a atenção de um grande número de pessoas, que estão otimistas quanto ao potencial que elas podem oferecer.

PROBLEMA

Quais são as principais características dos frameworks React Native e Flutter?

PROCEDIMENTOS METODOLÓGICOS

De acordo com Marconi e Lakatos (2017), os métodos científicos, são utilizados de maneira que um objetivo específico de uma pesquisa possa ser

(18)

alcançado, por meio de um sistema racional de atividades sistemáticas validadas com o objetivo de reduzir erros.

Sobre o conhecimento científico, Lakatos (1976) diz que tem como significado aquilo que é comprovado, isto é, quando é estabelecida a diferença entre a especulação e o conhecimento ou argumento formalmente provado.

Os procedimentos metodológicos utilizados neste trabalho são divididos em três etapas: finalidade, abordagem e por fim os procedimentos.

1.4.1 Finalidade

Este trabalho tem por finalidade aprofundar o conhecimento na área do desenvolvimento multiplataforma de aplicativos móveis utilizando os frameworks Flutter e React Native. O embasamento foi realizado através de artigos científicos cuja temática se relacionam ao desenvolvimento de aplicativos utilizando abordagem multiplataforma, artigos sobre o Flutter ou React Native, além das documentações disponíveis dessas tecnologias.

Com isso, foram realizadas duas implementações, com o objetivo de apresentar as principais características dos frameworks Flutter e React Native. As implementações foram realizadas visando a contribuição para o desenvolvimento de aplicativos móveis através da utilização de técnicas e ferramentas multiplataforma.

1.4.2 Abordagem

Este trabalho visa estudar as principais características dos frameworks React Native e Flutter utilizando como abordagem o método qualitativo de avaliação. Segundo Tuzzo e Braga (2016), a pesquisa qualitativa não se baseia na quantidade de dados, isso é, tem seu foco voltado para a qualidade e profundidade dos resultados.

1.4.3 Procedimentos

O procedimento utilizado para a realização deste trabalho segue a abordagem de pesquisa bibliográfica. Segundo Marconi e Lakatos (2017), pesquisa bibliográfica trata-se da compilação de trabalhos científicos cuja temática é relacionada ao tema e tem por objetivo direcionar e melhorar a qualidade da pesquisa. Através da coleta do

(19)

material é necessário realizar a filtragem com base nas constatações relevantes para o trabalho.

Para que seja feito o levantamento do conteúdo a ser utilizado na pesquisa, leva-se em consideração o plano de revisão sistemática (RBS). O termo revisão sistemática é usado para se referir a uma metodologia específica de pesquisa, desenvolvida a fim de reunir e avaliar as evidências disponíveis relativas a um tópico em foco (BIOLCHINI et al., 2005). Para tanto, o trabalho foi realizado em etapas de seleção dos artigos que consigam satisfazer os critérios da pesquisa e os requisitos propostos na RBS.

De acordo com Marconi e Lakatos (2017), a RBS serve para evitar esforços desnecessários sobre trabalhos que já tenham sido produzidos e chegar a um mínimo de entendimento sobre o assunto, com o objetivo de refinar as conclusões e salientar a contribuição da pesquisa.

A primeira etapa consiste no levantamento inicial do material de pesquisa. Este processo foi realizado por meio de buscas pelas palavras-chave expostas na RBS nas bases indicadas e mecanismos de buscas.

Na etapa seguinte, foi verificado se os documentos encontrados estão de acordo com os critérios estabelecidos. Este processo consiste em remover artigos duplicados, antigos ou que não correspondam à questão de pesquisa.

Os documentos que foram selecionados nas etapas anteriores foram armazenados em uma ferramenta de auxílio para organização de referências bibliográficas (Mendeley). Na sequência foi realizada a leitura dos artigos, visando constatar sua relevância para realização deste trabalho. O conteúdo relacionado a questão de pesquisa foi utilizado como parte da elaboração da fundamentação teórica do trabalho, possibilitando que os objetivos propostos neste trabalho fossem alcançados.

(20)

As etapas utilizadas nos procedimentos para realização deste trabalho são apresentadas na Figura 1.

Figura 1 - Metodologia para execução da pesquisa Fonte: Adaptado de (BIOLCHINI et al., 2015)

ESTRUTURA DO TRABALHO

O capítulo I traz a introdução, visando apresentar os objetivos gerais e específicos, bem como os procedimentos metodológicos utilizados.

O capítulo II traz o embasamento teórico da pesquisa, discorrendo sobre os conceitos das abordagens de desenvolvimento nativo e multiplataforma, complementado pela apresentação dos frameworks React Native e Flutter, suas arquiteturas técnicas e principais características.

No capítulo III é proposto uma análise comparativa entre os frameworks React Native e Flutter.

No capítulo IV é proposto o desenvolvimento de uma prova de conceito utilizando o React Native e o Flutter, apresentando as principais características de cada framework.

O capítulo V por fim, aborda as conclusões deste trabalho e as sugestões para trabalhos futuros.

Pesquisa nas bases indexadoras de artigos científicos

Busca por palavras-chave Filtragem dos artigos pelos critérios estabelecidos Armazenamento dos artigos na ferramenta Mendeley Elaboração da Fundamentação Teórica Apresentação dos frameworks React Native e Flutter Análise Comparativa Desenvolvimento dos aplicativos

(21)

FUNDAMENTAÇÃO TEÓRICA 2.1 DESENVOLVIMENTO NATIVO

Os aplicativos nativos são desenvolvidos utilizando um ambiente de desenvolvimento integrado (IDE), que fornece as ferramentas de desenvolvimento necessárias para criar e depurar os aplicativos. Além disso, podem ser executados apenas em celulares com a plataforma para qual foi desenvolvido (XANTOPHOULOS; XINOGALOS, 2013).

Na abordagem nativa, o aplicativo é criado para uma plataforma específica. Cada plataforma aceita diferentes linguagens de programação. O Android oferece o possível uso de Java ou Kotlin e o iOS oferece Objective-C ou Swift (NOGUEIRA, 2019).

Conforme descreve El-Kassas et al. (2017), as ferramentas que utilizam abordagem nativa fornecem APIs (Interface de Programação de Aplicações) para acessarem todos os recursos do dispositivo móvel, que são conjuntos de padrões de programação que definem interações entre softwares. Entre esses recursos estão: câmera, sensores, GPS (sistema de geolocalização), armazenamento de arquivos, lista de contatos entre outros recursos.

Uma vez que os aplicativos são desenvolvidos em ambientes próprios, deve-se deve-seguir os padrões técnicos, de interface e de experiência de usuário estipulados pela plataforma. Como todas as plataformas diferem significativamente uma da outra, os desenvolvedores que desejam atingir um grande público de usuários precisam desenvolver seus aplicativos para cada plataforma separadamente (HEITKÖTTER; HANSCHKE; MAJCHRZAK, 2013).

Figura 2 - Desenvolvimento Nativo

(22)

2.1.1 Vantagens do Desenvolvimento Nativo

Os aplicativos desenvolvidos especificamente para cada plataforma usando suas APIs e seguindo suas convenções, resultam na essência de uma aparência nativa (HEITKÖTTER; HANSCHKE; MAJCHRZAK, 2013). Considerando isso, aplicativos nativos aproveitam ao máximo o software e os recursos dos sistemas operacionais (NOGUEIRA, 2019).

De acordo com Tun (2014), o desempenho de aplicativos móveis nativos é uma de suas principais virtudes, pois eles são suportados pela API e pela interface do usuário (UI) nativa e recebem atualizações frequentes da biblioteca, portanto, eles podem tirar proveito da tecnologia disponível mais recente.

Com código nativo, elementos e controles comuns de interface do usuário são renderizados diretamente na tela através de APIs próprias da plataforma (CHARLAND; LEROUX, 2011).

Do ponto de vista do usuário final, os aplicativos nativos oferecem uma melhor experiência para o usuário. O código fonte é eficiente, com desempenho rápido, aparência e comportamento consistentes. O termo experiência do usuário refere-se à experiência do usuário em como usar o dispositivo. Esse é um fator importante, pois o usuário deve poder operar o aplicativo imediatamente após a instalação e também espera que o aplicativo funcione de maneira padrão (XANTOPHOULOS; XINOGALOS, 2013).

2.1.2 Desvantagens do Desenvolvimento Nativo

Conforme pode-se observar no item 2.1.1, o fato de o código escrito para desenvolver um aplicativo nativo em uma plataforma não poder ser reutilizado em outra plataforma, levanta o problema de que o mesmo precisa ser reescrito para que torne possível o uso do aplicativo em plataformas distintas.

Segundo El-Kassas et al. (2017), os aplicativos nativos são mais difíceis de desenvolver e exigem um alto nível de experiência, além de possuírem restrições e custos associados ao desenvolvimento e publicação em determinadas plataformas, o que inclui licenças de desenvolvedor e aprovações para a publicação de aplicativos nas lojas.

(23)

tempo e custo, devido a esforços duplicados para desenvolvimento e manutenção para cada plataforma. Eles também exigem um conjunto de ferramentas específico da plataforma (SDK), uma vez que cada sistema operacional vem com suas próprias ferramentas exclusivas (TUN, 2014).

Isso significa que uma equipe de desenvolvimento que deseja desenvolver aplicativos deve se concentrar em uma plataforma específica e desenvolver exclusivamente para essa, deixando de fora uma alta porcentagem de usuários ou realizar dois desenvolvimentos simultâneos com o custo de desenvolvimento correspondente, o que implica em mais tempo de desenvolvimento, custos mais altos de testes, manutenção e menor portabilidade (RODRÍGUEZ-SÁNCHEZ GUERRA, 2018)

Com base nisso, a escolha das duas ferramentas deste trabalho motiva-se, primeiro por tanto o Flutter como o React Native estarem entre as tecnologias multiplataforma mais procuradas, segundo o buscador do Google, através do Google Trends, conforme a Figura 3 a seguir.

Figura 3 - Frequência de busca dos termos React Native e Flutter Fonte: (GOOGLE, 2020)

Também em adicional, observa-se a movimentação por parte dos desenvolvedores no site Stack Overflow, onde o percentual de tópicos relacionados ao Flutter e React Native têm crescido exponencialmente nos últimos anos, conforme mostra a Figura 4.

(24)

Figura 4 - Percentual de tópicos sobre frameworks multiplataforma Fonte: (STACK OVERFLOW, 2020)

Dessa forma, este trabalho tem como objetivo buscar analisar essas duas tecnologias de desenvolvimento de aplicativos multiplataforma apresentando suas principais características.

2.2 DESENVOLVIMENTO MULTIPLATAFORMA

Conforme descrito no item 2.1, para que uma aplicação nativa possa ser executada em dispositivos de diferentes plataformas, é necessário a criação de uma aplicação para cada tipo de plataforma, o que exige tempo, investimento e uma equipe com conhecimento nas variadas tecnologias usadas pelas plataformas alvo.

Dito isso, El-Kassas et al. (2017) descreve que os desenvolvedores passaram a criar soluções multiplataforma em cima das soluções nativas, que tem como principal conceito o “write once, run anywhere” (WORA), isto é, desenvolver o aplicativo uma única vez e executá-lo em qualquer lugar.

Segundo Martinez e Lecomte (2017), os frameworks de desenvolvimento multiplataforma são construídos para economizar dinheiro e esforço de desenvolvimento, a fim de tornar o processo de desenvolvimento mais ágil e com uma única equipe construindo toda a solução.

Para Xanthopoulos e Xinogalos (2013), o principal objetivo do desenvolvi-mento de aplicativos móveis multiplataforma é alcançar o desempenho de aplicativos

(25)

nativos e executar no maior número possível de plataformas.

Os aplicativos multiplataforma são propostos como uma solução para o problema apresentado anteriormente. Esses aplicativos são desenvolvidos usando tecnologias de desenvolvimento da web, como HTML, CSS, JavaScript ou Dart, em vez de serem desenvolvidas no idioma nativo de cada plataforma (RODRÍGUEZ-SÁNCHEZ GUERRA, 2018)

Existem muitas ferramentas para desenvolvimento de aplicativos multiplata-forma e os usuários alvos diferem de acordo com os objetivos de cada ferramenta, desde pessoas sem conhecimento técnico para construção de aplicativos simples até desenvolvedores profissionais para construção de aplicativos avançados (EL-KASSAS et al., 2017). A Figura 5 ilustra o processo de desenvolvimento utilizando a abordagem multiplataforma.

Figura 5 - Desenvolvimento Multiplataforma

Fonte: Adaptado de (CORRAL; JANES; REMENCIUS, 2012)

2.2.1 Vantagens do Desenvolvimento Multiplataforma

Apesar da solução multiplataforma ainda ser bastante recente, é possível desenvolver aplicativos modernos com alto desempenho (YATSENKO et al., 2019). Para Fayzullaev (2018), entre as principais vantagens que o desenvolvimento multiplataforma traz, estão:

• Menor tempo de desenvolvimento; • Relação custo-benefício;

• Exposição a um número maior de usuários; • Sincronização em atualizações.

(26)

As soluções multiplataforma ajudam os desenvolvedores a escreverem o código do aplicativo apenas uma vez e executá-lo em diferentes plataformas. Portanto, em vez de escrever um novo código para cada plataforma, os desenvolvedores podem reutilizar o mesmo código em todas as plataformas. (EL-KASSAS et al., 2017).

Com uma única base de código, pode-se implantar o aplicativo em qualquer uma das principais plataformas de desenvolvimento móvel, tirando a necessidade de manter dois desenvolvimentos paralelos, economizando tempo e reduzindo custos (RODRÍGUEZ-SÁNCHEZ GUERRA, 2018).

O desenvolvimento de um aplicativo executado tanto no iOS quanto no Android oferece a vantagem adicional de entrar em um mercado maior, e a maioria das ferramentas de desenvolvimento multiplataforma permite o desenvolvimento para Android e iOS ou até mais plataformas. Além disso, a solução multiplataforma pode exigir menos desenvolvedores e, em combinação com a reutilização de código, o aplicativo pode chegar ao mercado mais rapidamente (FAYZULLAEV, 2018).

Levando em consideração essas características, Corral, Janes e Remencius descrevem que, uma vez que o aplicativo possui um único código, além do tempo e esforço de manutenção serem reduzidos, a abordagem multiplataforma facilita e unifica as atualizações para diversas plataformas ao mesmo tempo.

2.2.2 Desvantagens do Desenvolvimento Multiplataforma

Mesmo que o desenvolvimento multiplataforma tenha muitos benefícios, ele também apresenta muitas desvantagens e o mais notável é o desempenho e a interface do usuário não usual em comparação com aplicativos nativos (FAYZULLAEV, 2018).

Corral, Janes e Remencius (2012) descrevem que, para os usuários, o problema mais importante surge se a experiência do aplicativo não for a mesma que o aplicativo nativo correspondente, pois os aplicativos multiplataforma não exploram todos os recursos do dispositivo e podem não oferecer uma experiência de usuário nativa. Isso significa que os aplicativos podem apresentar problemas de desempenho e outras limitações em relação aos aplicativos nativos, afetando a experiência do usuário.

(27)

De acordo com El-Kassas et al. (2017), as soluções multiplataforma existentes ainda estão sendo pesquisadas e a maioria são baseadas em tecnologias da web, como HTML, ademais, apresentam falta dos últimos recursos introduzidos pelos sistemas operacionais, porque para cada atualização feita nos sistemas operacionais suportados pela ferramenta, o fornecedor deve atualizar sua própria ferramenta.

No que tange a questão de interoperabilidade, as equipes de desenvolvimento precisam estar cientes de que as ferramentas multiplataforma implicam no uso de linguagens e interfaces originalmente não destinadas a operar um dispositivo móvel e, como tal, isso pode gerar problemas (CORRAL; JANES; REMENCIUS, 2012).

2.3 COMPARATIVO DESENVOLVIMENTO NATIVO X MULTIPLATAFORMA

Cada plataforma possui seus próprios padrões, o que inclui arquitetura do aplicativo, interface do usuário etc. (PERCHAT; DESERTOT; LECOMTE, 2013). Para Corral, Janes e Remencius (2012), as equipes de desenvolvimento precisam estar cientes de que o uso de ferramentas multiplataforma utilizam linguagens e interfaces originalmente não destinadas a operarem em dispositivos móveis e, isso pode gerar problemas.

Como o conceito WORA não pode ser aplicado na criação de aplicativos nativos, a melhor opção alternativa para as empresas é o desenvolvimento entre plataformas. O desenvolvimento multiplataforma simplifica os processos de manutenção e implantação e economiza tempo e esforço de desenvolvimento (XANTHOPOULOS; XINOGALOS, 2013).

O Quadro 1 apresenta um comparativo entre as principais vantagens e desvantagens de cada abordagem. Este quadro foi baseado nas considerações dos seguintes autores: Corral, Janes e Remencius (2012), El-Kassas et al. (2017), Fayzullaev (2018), Rodríguez-Sánchez Guerra (2018) e Yatsenko et al. (2019).

(28)

Quadro 1 - Comparativo entre desenvolvimento nativo e multiplataforma

Abordagem Vantagens Desvantagens

Nativo

• Maior performance; • Maior acessibilidade aos recursos do dispositivo; • Melhor aproveitamento das capacidades do dispositivo; • Melhor utilização de recursos mais recentes do dispositivo; • Aparência e comportamento consistentes.

• Compatível apenas com a plataforma alvo;

• Maior custo de desenvol-vimento;

• Maior custo de manutenção; • Menor alcance de usuários; • Requer maior domínio em ferramentas fornecidas pela plataforma.

Multiplataforma

• Menor tempo de desenvol-vimento;

• Reutilização de código entre plataformas;

• Alcance a um maior número de usuários;

• Facilidade em manutenções e atualizações;

• Permite aplicar técnicas do desenvolvimento web.

• Menor desempenho; • Podem não oferecer uma experiência de usuário nativa. • Não explora todos os recursos dos dispositivos; • Requer atualizações frequentes para uso dos recursos mais recentes da plataforma.

Fonte: (do autor, 2020)

2.4 REACT NATIVE

O React Native é um framework JavaScript para construção de aplicativos móveis para iOS e Android. É baseado no React, a biblioteca JavaScript do Facebook para criação de interfaces web, contudo, o React Native tem como alvo plataformas móveis (EINSEMAN, 2017). De acordo com Novick (2017), o React Native usa a especificação ECMAScript1 2015 (ES6) para escrever código JavaScript moderno.

De acordo com Wu (2018), o React Native começou como um projeto interno de hackathon (evento de tecnologia realizado por profissionais ligados ao desenvolvimento de software) dentro do Facebook e seu objetivo inicial era unificar o processo de desenvolvimento entre plataformas iOS e Android. Em março de 2015, foi lançado oficialmente pelo Facebook, com código aberto e, desde então, está disponível no GitHub2 (NOVICK, 2017).

1 Linguagem de programação baseada em scripts. 2 Disponível em: https://github.com/facebook/react-native.

(29)

Uma vez que o React Native é uma ferramenta de código aberto, possui uma vasta comunidade de programação que contribui com o seu desenvolvimento (HANSSON; VIDHALL, 2016). As implementações da comunidade também fornecem suporte para Windows, Ubuntu, web entre outros (EINSEMAN, 2017).

Para Novick (2017), o React Native não é apenas um framework para uso externo, uma vez que, o próprio Facebook o utiliza na parte de grupos do seu aplicativo, que é uma combinação de módulos nativos e React Native, e também no Facebook Ads Manager, que, por sua vez, é construído inteiramente usando o React Native.

2.4.1 Arquitetura

Quando um projeto é iniciado, a Interface de Linha de Comando do React Native (CLI) gera um empacotador de código “packager” chamado Metro Bundler, que transforma todo o código JavaScript em um único arquivo: main.bundle.js. O código empacotado é executado por uma máquina virtual (VM) do JavaScript chamada JavaScriptCore. A partir disso, é gerado um encadeamento entre o código JavaScript e o código nativo (NOGUEIRA, 2019).

O React Native se comunica com as APIs nativas do dispositivo por meio da bridge (ponte). A bridge é responsável por realizar a comunicação entre o lado JavaScript e o lado nativo do aplicativo (HANSSON; VIDHALL, 2016). De acordo com Novick (2017), a bridge é a camada que conecta os módulos JavaScript e nativos por meio de chamadas assíncronas, contendo os dados vindos do JavaScript serializados em lotes para os módulos nativos.

Para Eisenman (2015), a bridge traduz as chamadas JavaScript e chama as APIs da plataforma alvo e os elementos da interface do usuário necessários (Objective-C ou Java). Uma vez que esse processo não é executado diretamente na UI, ele pode realizar essas chamadas assíncronas sem afetar a experiência do usuário.

(30)

Na Figura 6 é representado como a arquitetura do React Native é estruturada e como é realizada as interações entre as partes.

Figura 6 - Arquitetura do React Native Fonte: Adaptado de (NOVICK, 2017)

2.4.2 Virtual DOM

Para entender os fundamentos técnicos do React Native, é importante entender um pouco sobre o conceito do Virtual DOM (Document Object Model), que é um dos principais conceitos do React. Segundo Wu (2018), uma das principais razões pelas quais os aplicativos React Native podem ser executados em plataformas diferentes é devido ao uso do Virtual DOM.

Primeiramente, DOM trata-se de um modelo de estrutura em árvore em que cada nó é um objeto que representa uma parte do documento HTML (WU, 2018). No entanto, a manipulação do DOM pode ser um processo caro, isso significa que renderizar dados no navegador é uma operação custosa (EINSEMAN, 2017).

Segundo Novick (2017), o Virtual DOM, por sua vez, é uma representação dessa mesma estrutura, porém dentro do JavaScript e sem acessar diretamente os nós do HTML.

No React, o Virtual DOM atua como uma camada entre a descrição do desenvolvedor de como as coisas devem parecer e o trabalho realizado para que sua aplicação realmente seja renderizada na página. Dessa forma, em vez de renderizar

(31)

diretamente as alterações na página, o React calcula na memória apenas as alterações necessárias e renderiza a quantidade mínima de componentes (EINSEMAN, 2017).

Figura 7 - Como o React calcula as alterações no Virtual DOM Fonte: Adaptado de (EINSEMAN, 2017)

No React Native, em vez de renderizar para o DOM do navegador, são feitas chamadas às APIs de Objective-C para renderizar em componentes iOS ou APIs Java para renderizar em componentes Android (EINSEMAN, 2017). Neste processo, ele criará o Virtual DOM usando a VM do JavaScript e enviará a visualização resultante para a UI através da bridge (HANSSON; VIDHALL, 2016).

2.4.3 JSX

Os aplicativos React Native são escritos com uma mistura de JavaScript e marcação XML, conhecida como JSX (EINSEMAN, 2017). O JSX é uma extensão de sintaxe semelhante ao XML para ECMAScript sem nenhuma semântica definida. que deve ser usado pelos pré-processadores para transformar esses tokens no ECMAScript padrão (FACEBOOK INC., 2014).

Para Novick (2017), podemos considerar que o JSX se destina a ser usado pelos pré-processadores para transformar textos semelhantes ao HTML encontrados nos arquivos JavaScript em objetos padrões, possibilitando que o motor JavaScript

(32)

(engine) possa analisá-los.

Ao se analisar um código escrito no React Native, um dos pontos mais fáceis de serem observados é o uso de JSX, uma vez que, é utilizado fundamentalmente para descrever como os componentes da interface do usuário devem aparecer (WU, 2018).

Segundo Eisenman (2015), no React Native o JSX aplica rigorosamente a priorização da separação de tarefas designadas aos componentes. Uma vez que não é executado em um navegador, faz mais sentido unificar estilos, marcações e comportamentos em um único arquivo para cada componente.

A Figura 8 representa como um componente JSX é definido no React. Neste exemplo o componente é representado pelo nome Welcome e tem por característica exibir o um texto de boas vindas na tela.

Figura 8 - Exemplo de declaração de um componente JSX no React JS Fonte: (do autor, 2020)

2.4.3.1 Props

O React JS possui um sistema para passar dados de um componente para outro e criação de hierarquias de componentes. Este processo é realizado através da passagem de atributos JSX em um único objeto, chamado de props “propriedades” (NOVICK, 2017).

Segundo descreve Fedosejev (2015), as props podem ser definidas como sendo um objeto JavaScript passado de um elemento pai para um elemento filho com algumas propriedades que são consideradas imutáveis, ou seja, aquelas que não

(33)

podem sofrer alterações.

De acordo com Wu (2018), as props definem a configuração de um componente, ou seja, devem ser usadas para personalizar os componentes quando eles são criados, podendo estar até mesmo vazia, se corresponder às necessidades, no entanto, uma vez que é definida, nunca poderá ser alterada.

As props são passadas para um componente de maneira semelhante à forma como os atributos HTML são passados na web, mas o valor da prop deve estar entre chaves ou entre aspas para strings. Se os valores estiverem entre chaves, eles podem ser variáveis e expressões JavaScript. (NOVICK, 2017). Considerando isso, as props podem ser adicionadas aos componentes e utilizadas para apresentar dados dinâmicos quando renderizados (DANIELSSON, 2016).

Na Figura 9 é demonstrado como as props podem ser passadas para um componente JSX no React JS.

Figura 9 - Utilizando props no React JS Fonte: Adaptado de (REACT JS, 2020a)

Diferente do React JS, no React Native não utiliza-se tags HTML, mas sim componentes nativos respectivos da plataforma que serão introduzidos no item 2.4.4. Na Figura 10 observa-se a diferença na escrita do código JSX no React Native utilizando as props em relação ao React JS.

(34)

Figura 10 - Utilizando props no React Native Fonte: Adaptado de (NATIVE, 2020b)

2.4.3.2 States

Conforme o item 2.4.3.1, observa-se que as props são definidas pelo componente pai e são fixas ao longo da vida útil do componente. Por outro lado, para realizar alterações em componentes, utiliza-se o conceito de estado “states” (NATIVE, 2020c).

No React existem dois tipos de componentes, os componentes com estado “stateful” e os componentes sem estado “stateless” (NOVICK, 2017). Os states são utilizados para controlar o estado dos componentes de acordo com as ações feitas pelo usuário (DANIELSSON, 2016).

De acordo com Novick (2017), os componentes stateful armazenam informações na memória sobre o estado de um componente, podendo também alterá-lo. Já os componentes stateless calculam seu estado interno, mas nunca o altera diretamente, isto é, independente da ação, sempre produzirá a mesma saída.

Para Novick (2017), o componente stateful é o componente responsável por alterar o estado e transmiti-lo as props. A esse respeito Danielsson (2016) observa que a minoria dos componentes do aplicativo são stateful, pois eles devem estar no topo da hierarquia de componentes. Assim, ficam responsáveis por encapsular toda a lógica de interação e gerenciamento de estado, os passando pela hierarquia para os componentes stateless através das props.

(35)

As alterações no estado de um componente só podem ser feitas através da função setState. Quando chamada, ela envia uma atualização para o objeto que controla o estado do componente. Assim que o estado é alterado, o componente é renderizado novamente com suas novas informações (REACT JS, 2020b).

Figura 11 - Utilização do state no React Native Fonte: Adaptado de (NATIVE, 2020c)

2.4.4 Componentes Nativos

No React Native os componentes são escritos utilizando o JavaScript. Em tempo de execução, o React Native cria as visualizações nativas correspondentes para esses componentes, utilizando Java no Android e Objective-C no iOS. Esses componentes baseados na plataforma alvo são chamados de componentes nativos (NATIVE, 2020d).

Segundo Eisenman (2015), o React Native fornece os seguintes componentes básicos que geralmente são usados na grande maioria dos aplicativos: View, Text, Image e TextInput. Estes componentes serão apresentados a partir do item 2.4.4.2.

2.4.4.1 Estilização em Componentes Nativos

De acordo com Eisenman (2015), as plataformas fora da web têm uma ampla gama de abordagens de estilos. No caso do React Native, utiliza-se uma abordagem padronizada para estilização.

O React, como estrutura básica do React Native, tem um forte impacto sobre como os aplicativos React Native são organizados e desenvolvidos. Da perspectiva

(36)

da web e da influência do CSS, o estilo é tratado como regra fundamental ao ser aplicado aos componentes. No entanto, isso não significa que o aplicativo React Native pode usar diretamente arquivos CSS (WU, 2018).

Segundo Novick (2017), no React Native existem algumas diferenças importantes em relação ao CSS utilizado na web, além do fato de que suas propriedades também se comportam de maneira um pouco diferente. Entre essas diferenças pode-se destacar:

• As propriedades são nomeadas em camelCase; • Todos os elementos são flexíveis por padrão; • O eixo vertical é o eixo principal na UI;

• Não existem unidades como o pixel. Para isso, utiliza-se apenas o valor numérico.

Ao contrário da web, onde o suporte a CSS varia entre os navegadores, no React Native existe um conjunto consistente de regras de estilo a serem seguidas (EISENMAN, 2015). A esse respeito, Wu (2018) destaca que as principais técnicas de estilização em componentes no React Native podem ser feitas utilizando inline styles (estilização embutida no componente), objetos Javascript ou utilizando a classe própria para estilizações StyleSheet do React Native.

Para Einseman (2017), os inline styles são a forma mais simples de estilizar componentes, pois são fáceis de aplicar, permitindo que você experimente rapidamente o resultado gerado. Porém, de maneira geral, não é a opção mais adequada, pois são menos eficientes uma vez que os objetos devem ser recriados em cada renderização.

Na Figura 12, observa-se o uso do Text em conjunto com o inline styles.

Figura 12 - Componente Text utilizando inline styles Fonte: Adaptado de (NOVICK, 2017)

Segundo Wu (2018), para um processo mais otimizado em relação ao inline styles, o React Native fornece uma classe especial chamada StyleSheet, que é

(37)

responsável pela construção de objetos JavaScript que incluem CSS. Estes objetos são criados fora do escopo do componente e podem ser aplicados posteriormente, evitando que os objetos de estilos sejam recriados a cada nova renderização.

De acordo com Eisenman (2015), criar folhas de estilos com o StyleSheet em vez de utilizar objetos JavaScript diretamente pode reduzir o número de alocações na memória, pois são imutáveis, gerando assim um maior desempenho e melhor qualidade de código. Uma vez que o StyleSheet é importado no arquivo do componente, os métodos disponíveis pela sua API podem ser utilizados conforme a necessidade.

Segundo Novick (2017), para criação de objetos de estilos utiliza-se exclusivamente o método create do StyleSheet, conforme ilustrado na Figura 13.

Figura 13 - Objeto de estilos utilizando Stylesheet Fonte: Adaptado de (NOVICK, 2017)

2.4.4.2 View

Segundo Eisenman (2015), no React Native o componente View é o mais básico dos componentes, que é um elemento de UI simples e flexível. Ele representa um container que oferece suporte a estilização, tratamento de toques na tela e controles de acessibilidade (NATIVE, 2020e).

Para Novick (2017), o componente View é o mais importante para construir a UI, uma vez que é projetado para agrupar outros componentes, tem um papel fundamental na organização e distribuição de elementos na tela, semelhante a tag div do HTML.

(38)

A Figura 14, traz um exemplo de componente View e seu conteúdo interno.

Figura 14 - Componente View Fonte: Adaptado de (NOVICK, 2017)

2.4.4.3 Text

Renderizar texto é uma função aparentemente básica; quase qualquer aplicativo precisará fornecer texto em algum lugar. No entanto, os textos dentro do contexto do React Native funcionam de maneira diferente da renderização de texto para a web (EINSEMAN, 2017).

De acordo com Novick (2017), o componente Text é usado no React Native para exibir qualquer tipo de texto na tela. Além disso, este componente suporta estilização e várias opções de toque.

Apenas os componentes Text podem armazenar textos simples no React Native. No HTML podemos inserir textos dentro de uma div, por exemplo. Já no React Native, não é possível fazer o mesmo em um componente como a View (EINSEMAN, 2017). Na Figura 15, observa-se como o componente Text pode ser utilizado em conjunto com um objeto de estilos do StyleSheet.

Figura 15 - Componente Text utilizando StyleSheet Fonte: Adaptado de (NOVICK, 2017)

(39)

2.4.4.4 Image

No desenvolvimento web é possível incluir imagens de várias maneiras; sendo mais comum através do elemento “img” no HTML, ou diretamente pelo CSS com a propriedade background-image. No React Native, o componente Image é um dos componentes básicos responsável por lidar com as imagens dentro do aplicativo (EINSEMAN, 2017).

Conforme descreve Novick (2017), o uso do componente Image é simples e direto; basta definir a propriedade source indicando o caminho (path) onde a imagem se encontra. Também é possível incluir imagens diretamente da internet através de seu endereço URL, porém, neste caso é necessário especificar as dimensões da imagem manualmente. A Figura 16 traz um exemplo do componente Image utilizando endereço URL.

Figura 16 - Componente Image utilizando endereço URL Fonte: Adaptado de (NOVICK, 2017)

2.4.4.5 TextInput

Segundo Novick (2017), o TextInput é o componente básico que permite ao usuário inserir texto, podendo lidar com textos simples e senhas.

Além de inserir textos, o TextInput possui propriedades que fornecem configurações para vários recursos, como correção automática, formatação entre maiúsculas e minúsculas e diferentes tipos de teclado, como teclado numérico (NATIVE, 2020f).

Danielsson (2016) descreve que os valores dos campos nos componentes TextInput são armazenados como states e devem ser atualizados sempre que o valor no campo é alterado por meio da propriedade onChangeText, conforme ilustrado na Figura 17.

(40)

Figura 17 - Componente TextInput Fonte: (NATIVE, 2020f)

2.4.5 Componentes específicos da plataforma

Quando a maior parte do código do aplicativo é multiplataforma, é necessário algum tipo de sistema para detectar adequadamente quando há casos extremos em que precisa-se usar componentes dependentes de plataforma (NOVICK, 2017).

Para tanto, existem componentes que são compatíveis apenas para uma plataforma específica. Estes componentes são nomeados com um sufixo apropriado (IOS ou Android), como por exemplo o TabBarIOS e o ToolbarAndroid. Geralmente esses componentes são específicos pois envolvem algum tipo de API exclusivamente da plataforma em questão, o que significa que caso sejam colocados na plataforma errada, o aplicativo irá travar (BONNIE EISENMAN, 2015).

De acordo com Novick (2017), existem duas maneiras de detectar a plataforma em que o aplicativo está sendo executado no React Native. Para isso, é necessário primeiramente importar o módulo Platform que providencia a constante OS e o objeto select que podem ser utilizados conforme demonstrado na Figura 18.

Figura 18 - Detectando a plataforma atual no React Native Fonte: Adaptado de (NOVICK, 2017)

(41)

Para Eisenman (2015), a API do módulo Platform pode ser útil quando é necessário ajustar alguns elementos com base na plataforma, tirando a necessidade de implementar os componentes separadamente.

2.4.6 Navegação

A navegação no contexto de aplicativos móveis, se refere ao código que permite aos usuários fazer a transição de uma tela para outra (EISENMAN, 2015).

No React Native existe o React Navigation, que fornece uma solução de navegação direta, com a capacidade de apresentar navegação em pilha comum e padrões de navegação com guias no Android e iOS. As rotas do aplicativo devem estar envoltas em um componente NavigationContainer (NATIVE, 2020g).

Além de realizar a transição entre telas, também permite links diretos, para que os usuários possam acessar uma tela específica no aplicativo através de um endereço URL, por exemplo (NOVICK, 2017).

O React Navigation fornece várias formas que determinam a estrutura de navegação do aplicativo, entre elas o StackNavigator. O StackNavigator possui o método createStackNavigator que fornece um agrupamento de telas em formato de pilha e permite renderizá-las e realizar transições entre elas (EISENMAN, 2015).

Figura 19 - Pilha de rotas StackNavigator Fonte: Adaptado de (NATIVE, 2020g)

(42)

Cada tela contida no StackNavigator possui uma propriedade component que é um componente React. Esses componentes recebem uma prop chamada navigation, que possui vários métodos para vincular a outras telas. Para navegar de uma tela para outra, utiliza-se o método navigate (NATIVE, 2020g).

O método navigate, recebe como parâmetro o nome da tela conforme definido na configuração de rotas e o objeto contendo os valores que serão passados para a próxima tela (NOVICK, 2017).

Figura 20 - React Navigation método navigate Fonte: Adaptado de (NATIVE, 2020g) 2.5 FLUTTER

Flutter é um framework multiplataforma projetado para permitir a reutilização de código em sistemas operacionais como Android e iOS, enquanto também permite que os aplicativos possam acessar diretamente os recursos da plataforma em que está sendo executado (FLUTTER, 2020b).

Desenvolvido e mantido pelo Google, o Flutter visa o desenvolvimento de aplicativos móveis de alto desempenho e foi anunciado publicamente pela primeira vez no ano de 2016 (WU, 2018). Para Napoli (2019), o Flutter é um framework de UI para a construção de aplicativos modernos, nativos e reativos para Android e iOS.

De acordo com Fayzullaev (2018), o Flutter começou como um experimento realizado por membros da equipe do navegador Google Chrome, onde buscavam criar um mecanismo de renderização rápida em aplicativos móveis.

Todos os aplicativos no Flutter são escritos em Dart, que é uma linguagem de programação que foi criada pelo Google inicialmente com o objetivo de substituir o concorrente JavaScript (WU, 2018).

(43)

2.5.1 Arquitetura

O Flutter é projetado como um sistema extensível em camadas. Ele existe como uma série de bibliotecas independentes, cada uma dependendo da camada subjacente, sendo elas: framework, engine e embedder (FLUTTER, 2020b).

A Figura 21 ilustra como as camadas que compõem a arquitetura do Flutter são divididas.

Figura 21 - Arquitetura do Flutter Fonte: Adaptado de (FLUTTER, 2020b)

A camada framework representa uma estrutura reativa moderna escrita na linguagem Dart e inclui um rico conjunto de bibliotecas como classes básicas para construção de UI, animações, gestos entre outras. Em termos de layout e renderização, fornece um mecanismo de abstração para lidar com a UI através de elementos chamados widgets (FLUTTER, 2020b).

Segundo Napoli (2019), a camada engine (motor) é construída com as linguagens C/C++ e dá acesso às APIs específicas do Android e iOS comunicando-se por meio de canais de plataforma. Além disso, fornece a VM do Dart (Dart runtime) e utiliza um mecanismo de renderização 2D (Skia).

O código C/C++ da camada engine é compilado com NDK3 do Android e

LLVM4 no iOS, respectivamente, e todo o código Dart é compilado para código nativo

através do recurso de compilação ahead-of-time (AOT), isto é, compilação antes do

3 Conjunto de ferramentas para programação em C/C++ no Android. 4 Compilador de código C/C++ para código nativo no iOS.

(44)

tempo (WU, 2018). Em ambos os casos o aplicativo é executado usando o conjunto de instruções nativas propriamente definidas através da VM do Dart (FAYZULLAEV, 2018).

A camada embedder, por sua vez, fornece um ponto de entrada e coordena com o sistema operacional atual para acesso a recursos, gerenciar eventos e mensagens e utiliza a linguagem apropriada para a plataforma, sendo Java para Android e Objective-C para iOS (FLUTTER, 2020b).

2.5.2 Widgets

Widgets são elementos de construção básicos de uma UI que afetam e controlam a visualização e a aparência dos aplicativos desenvolvidos em Flutter. Cada widget é uma declaração imutável de uma parte da UI e especifica seu próprio modelo de representação, o que permite uma forte otimização (FAYZULLAEV, 2018).

Wu (2018) descreve os widgets como sendo uma das partes mais importante em um aplicativo Flutter, pois são vistos diretamente pelos usuários, logo, precisam ser corretamente configurados. Além de definir como os elementos visuais se comportam, os widgets também manipulam e respondem as ações do usuário. Portanto, é crucial que sejam performáticos, incluindo renderizações e animações.

Pode-se considerar que no Flutter tudo é um widget, uma vez que engloba desde elementos tradicionais como botões, textos e ícones até elementos de estilos como tipografía e esquemas de cores (FAYZULLAEV, 2018).

Os dois principais tipos de widgets no Flutter, que são os com estado (stateful widgets) e os sem estado (stateless widgets). O stateful widget possui um objeto correspondente que representa o seu estado e descreve como o widget responde às interações do usuário. Por outro lado, o stateless widget é um componente mais simples que não responde à reação do usuário (WU, 2018).

Os stateful widgets são úteis quando a parte da interface do usuário que está sendo descrita pode mudar dinamicamente. Já os stateless widgets são úteis quando essa parte não depende de nada além das informações de configuração no próprio objeto (FLUTTER, 2020c). Segundo Wu (2018), o princípio de manipulação de estado permite que o próprio widget se mantenha imutável, evitando assim que a camada de visualização renderize o widget com frequência.

(45)

O Quadro 2 ilustra as principais diferenças entre stateful e stateless widgets no Flutter.

Quadro 2 - Diferenças entre widgets stateful e stateless no Flutter

Tipo Composição Dinâmica Imutável Objeto de controle de estado

stateful Sim Sim Sim

stateless Não Sim Não

Fonte: Adaptado de (WU, 2018)

De acordo com Payne (2019), assim como em em várias outras linguagens, um aplicativo Flutter inicia a partir de uma função principal (main). A função main irá chamar uma função chamada runApp, que recebe como parâmetro um widget raiz que pode ter qualquer nome, mas deve herdar da classe StatelessWidget, como demonstrado na Figura 22.

Figura 22 - Função runApp Flutter Fonte: Adaptado de (PAYNE, 2019)

Ao executar a função runApp, o Flutter processa todos os widgets contidos no widget raiz. Após isso, cada elemento correspondente é devidamente montado e renderizado (NAPOLI, 2019).

(46)

2.5.3 Widgets básicos

Ao construir aplicativos no Flutter, geralmente serão utilizados os widgets básicos fornecidos, portanto é necessário estar familiarizado com eles (NAPOLI, 2019). O Flutter vem com um conjunto de widgets básicos, dos quais os seguintes são comumente usados: Container, Text, Row e Column (FLUTTER, 2020c).

2.5.3.1 Container

O Flutter abstraiu muitos conceitos de outras tecnologias, incluindo o HTML da web, que possui mecanismos para agrupamento de elementos. Considerando isso, o Flutter tem um widget semelhante a div do HTML, chamado Container, contudo, o Container pode conter apenas um widget filho (PAYNE, 2019).

A propriedade child do Container é utilizada para inserir um widget filho e seu uso é opcional. Além disso, o Container possui diversas propriedades para controles de dimensionamento, cores, margens, bordas entre outras (NAPOLI, 2019).

O comportamento do Container segue uma série de regras de layout para que seu resultado seja adequado. Para isso, ele tenta seguir o alinhamento, se adequar para a dimensão do widget filho, respeitar as dimensões e restrições e ocupar o menor espaço possível (FLUTTER, 2020d). Um exemplo de widget Container e algumas de suas propriedades podem ser utilizados conforme elucidado na Figura 23.

Figura 23 - Widget Container Fonte: Adaptado de (NAPOLI, 2019)

2.5.3.2 Text

No Flutter qualquer sequência de caracteres é exibida pelo widget Text. Seu construtor recebe os argumentos string e style, que definem o texto a ser exibido e sua estilização, mas também pode receber outros argumentos como maxLines,

(47)

overflow, textAlign entre outros. O construtor é utilizado para inicializar e personalizar o widget (NAPOLI, 2019).

O texto é exibido com um único estilo, sendo que a sequência de caracteres pode quebrar em várias linhas ou pode ser exibida na mesma linha, dependendo das restrições definidas. A propriedade style é opcional, sendo assim, quando omitido, o texto usará o estilo padrão de textos definido pelo elemento pai mais próximo (FLUTTER, 2020e).

Figura 24 - Widget Text

Fonte: Adaptado de (FLUTTER, 2020e)

Para inserir estilos no widget Text, existe uma classe específica chamada TextStyle, que pode ser instanciada dentro da propriedade style. O TextStyle contém cerca de 20 propriedades para estilização de texto como cor, tamanho, fonte entre outras (PAYNE, 2019).

Figura 25 - Widget Text com TextStyle Fonte: Adaptado de (FLUTTER, 2020f)

(48)

2.5.3.3 Row

O Row é um widget simples que tem por funcionalidade exibir seus widgets filhos em uma matriz horizontal (FLUTTER, 2020g). Para isso, é necessário utilizar a propriedade children passando um vetor de widgets (NAPOLI, 2019).

Figura 26 - Widget Row Fonte: Adaptado de (PAYNE, 2019)

Caso o conteúdo inserido no Row for mais largo do que a própria linha, a linha será considerada estourada. Para evitar isso, os widgets filhos podem ser envoltos pelo widget Expanded (FLUTTER, 2020g). Quando um filho de um Row ou Column é envolto pelo Expanded, torna-se flexível, isto é, caso houver espaço extra, ele se estenderá ao longo do eixo principal para preencher esse espaço (PAYNE, 2019).

A Figura 27 ilustra como o widget Row pode ser definido em conjunto com o widget Expanded.

Figura 27 - Widget Row com widget Expanded Fonte: Adaptado de (PAYNE, 2019)

(49)

A Figura 28 traz um exemplo de como o widget Row se comporta na tela. Neste exemplo, a linha é composta por 3 elementos idênticos alinhados horizontalmente.

Figura 28 - Comportamento widget Row Fonte: Adaptado de (NAPOLI, 2019)

2.5.3.4 Column

Segundo Napoli (2019), o widget Column funciona da mesma forma que o Row, porém seus filhos são alinhados verticalmente sem ocupar toda a altura da tela. Assim como no Row, cada widget filho pode ser incorporado em um widget Expanded para preencher o espaço disponível, assim como demonstrado na Figura 29.

Figura 29 - Widget Column Fonte: Adaptado de (PAYNE, 2019)

Todos os widgets inseridos na propriedade children serão exibidos na ordem em que forem adicionados. É possível até mesmo ter linhas dentro das colunas e vice-versa (PAYNE, 2019). O comportamento de um widget Column ocorre assim como ilustrado na Figura 30.

Referências

Documentos relacionados

Para disciplinar o processo de desenvolvimento, a Engenharia de Usabilidade, também conceituada e descrita neste capítulo, descreve os métodos estruturados, a

Para essa implementação deve-se observar que muitos sistemas têm sido construídos baseados exclusivamente em requisitos técnicos, deixando a arquitetura implícita

Conclui-se, portanto, que o processo de implementação da nova organização curricular, que traz o Trabalho de Conclusão de Curso como requisito obrigatório para obtenção do

Hoje o gasto com a saúde equivale a aproximada- mente 8% do Produto Interno Bruto (PIB), sendo que, dessa porcentagem, o setor privado gasta mais que o setor público (Portal

Para atingir este fim, foram adotados diversos métodos: busca bibliográfica sobre os conceitos envolvidos na relação do desenvolvimento de software com

Objetivo: Garantir estimativas mais realistas e precisas para o projeto, ao considerar nesta estimativa o esforço necessário (em horas ou percentual do projeto) para

Para identificar quais treinamentos serão necessários para cada trabalhador ou equipe dentro de uma organização desenvolver um programa eficaz de T&D, pode-se buscar

A ordenação típica era de Atenas, Mileto e Priene, onde as muralhas rodeiam “com folga”, tanto as áreas planejadas como as outras, aproveitando ao máximo as características