News & Events
Tutorial: Criando meu app step-by-step – Parte I
- 14 de setembro de 2014
- Posted by: Adriano Santos
- Category: Android delphi Desenvolvimento embarcadero Notícias Tutoriais XE4 XE5 XE6 XE7
O desenvolvimento de aplicações móveis utilizando Delphi tem gerado muito “pano pra manga” em comunidades Delphi nas redes sociais. Com o interesse cada vez maior, de programadores novos ou experientes, em desenvolver apps com a ferramenta, surgem também as dúvidas. Muitas comuns como o simples fato de navegar entre telas de um app ou ainda dúvidas mais avançadas como o uso de Bluetooph com Delphi em iOS e Android. Muito bem, baseado nisso resolvi criar alguns posts com orientações e um passo-a-passo explicando as principais dúvidas encontradas pela internet.
Nesse primeiro post vamos começar do início:
- Criação da app;
- Criação do layout;
- Navegação entre as abas;
- Navegação entre formulários.
Requisitos:
- Delphi XE5 ou superior;
- Aparelho Android;
- Aparelho iPhone com iOS 7 ou superior (caso deseje testar no iOS);
Obs 1. Serei bastante detalhista no início para abranger iniciantes e experts.
Obs 2. Usarei nesses primeiros posts o RAD Studio XE6, devido ao novo recurso de formulários Master que terei que explicar em um segundo momento separado.
Criação da App
Vamos começar, evidentemente, abrindo o Delphi e criando a aplicação salvando-a em um diretório de nossa preferência. Utilize o menu File > New > Multi-Device Application – Delphi (no XE7, em XE5 e 6 o nome do menu é diferente, apenas verifique o correto). (Figura 1)
Figura 1. Início da aplicação
Na tela que se abre, escolhemos o layout inicial de nossa aplicação. Não se preocupe com isso agora, podemos mudar com o tempo. Portanto, vamos escolher a opção Blank Application.
Somos levados ao primeiro Form de nossa app e vamos chama-la de frmMain (Principal). Existem milhares de técnicas diferentes para criar nosso layout e a navegação do aplicativo, mas nesse caso vou mostrar como eu tenho criado meus aplicativos em minha empresa, assim fica como sugestão.
Para quem já está utilizando o Delphi XE7, deve estar visualizando algo diferente na IDE. São os layouts Master. Agora é possível criar um layout principal e deixar que a IDE selecione o correto para cada dispositivo no momento de abertura de nosso form. Mas isso é assunto para outros posts, por enquanto vamos nos focar em celulares Android e iOS de 4″. Para isso selecione Android 4″ Phone caso esteja no XE7, os demais leitores que estão em versões anteriores utilizem as opções Google Nexus 4 ou Samsumg Galaxy S2/S4, etc. (Figuras 2 e 3)
Criando meu app step-by-step
Figura 2. Definição de Layout no XE7
Figura 3. Definição de Layout XE4,5 e 6
Feito isso o que vamos começar a fazer é entender ao certo como nossa app irá se comportar. Tive a ideia de criar um app para controle de locadora (Quem nunca fez um sistema de locadora ao fazer um curso de programação, não é mesmo? ;)), pois já estamos familiarizados com algumas das tabelas e informações que uma locadora precisa ter para funcionar.
Nesse primeiro momento faremos a criação de nossas listas sem o uso de banco de dados, ou seja, aprenderemos a usar o esquema de Prototipação do Delphi criando dados fictícios para visualizarmos o funcionamento do app.
Salvemos o projeto então. Na propriedade Name do formulário insira o texto “frmMain” (sem as áspas) e salve o formulário usando File > New > Save As… Dê o nome de UntMain e salve-o no diretório que desejar. Em seguida salve o projeto usando File > New > Save Project As… Dei o nome de LocadoraDelphi.dproj
Definição do Layout
Muito bom. A primeira coisa a se definir, na minha opinião, é desenhar como a aplicação deverá se comportar. Eu me utilizo de várias técnicas para isso. Como não sou designer, mas tenho alguma noção de desenho, comprei um bloco de folhas A3 tipo flipcharting onde costumo desenhar, rusticamente claro, o fluxo da minha aplicação. (Figura 4).
Figura 4. Folha A3 para desenho
Para quem não tem a mínima noção de desenho, existem inúmeras ferramentas no mercado que ajudam nesse quesito. Mas enfim, não é nosso foco aqui. Vamos desenhar na nossa mente mesmo o que desejamos que nosso app tenha. Proponho as seguintes telas:
- Login e Senha;
- Lista de Títulos;
- Lista de Usuários/Clientes;
- Lista de Títulos Alugados;
- Alugar: Tela para definir o aluguel para um cliente;
- Baixar Título Alugado;
A ideia é que o app seja utilizado pelo administrador da ocadora como se fosse a extensão de seu programa de uso no desktop da loja, onde o cara poderá consultar rapidamente algumas informações sobre o título. Nossa tela default ser a Lista de Títulos que deverá abrir logo que de início. Faremos um Login e Senha utilizando Parse.com como backend de banco de dados para facilitar e aprender a usar o serviço;
Teremos também um menu no estilo Facebook Mobile que se popularizou bastante, ou seja, abriremos as opções tocando em um botão com Detalhes e o menu se abrirá na lateral.
Criando o menu inicial
Para criamos o menu inicial, vamos utilizar um TLayout e um TListBox. Ambos devem ser colocamos no formulário e NÃO um dentro do outro. Adicione primeiro o TLayout e faça as seguintes configurações:
- Name: lytMain;
- Align: Client;
Agora adicione um TListBox no Form e então faremos uma série de mudanças nele conforme mais abaixo.
#Dica: Caso tenha dificuldades em selecionar o Form principal já que o TLayout ficou por cima de tudo, apenas clique no TLayout e pressione 1x o ESC. Isso fará com que o Form seja selecionado.
E caso já tenha adicionado o TListBox dentro do TLayout, basta acessar a caixa de estrutura e mover o TListBox para cima do Form;
Configure o TListBox como segue:
- Name: lstMnuMain
- Align: Cient
- GroupKind: Grouped
- StyleLookup: transparentlistboxstyle
Agora que configuramos as principais propriedades, precisamos adicionar os itens que serão nossos Itens de Menu. Agruparemos em categorias, por isso utilizamos a propriedade GroupKind para dar um aspecto mais profissional acrescido do StyleLookup como Transparent.
Obs. Em dado momento faremos a personalização da aplicação incluindo um layout mais customizado
Clique agora com o botão direito no TListBox e escolha Items Editor… para acessarmos o gerenciador de itens do ListBox. No ComboBox à direita da caixa, encontramos os tipos de itens que podemos adicionar. Usaremos sempre dois tipos (Figura 5):
- TListBoxGroupHeader: Cabeçalho do Grupo;
- TListBoxItem: Item
Figura 5. Tipos de Item de ListBox
Figura 6. Ordem os menus
Adicione 2 (dois) TListBoxGroupHeader e 4 (quatro) TListBoxItem e coloque-os na ordem da Figura 6. Cada item do ListBox possui suas propriedades, isso significa que podemos utilizar a propriedade Text como “Caption” do nosso menu e ainda outras propriedades como ItemData para adicionar um botão Acessory e uma imagem para ele.
#Dica: Em Mobile, os botões (figuras) que ficam à direita do item na lista são chamados de Acessory (Acessório). Servem para indicar se o item possui um “Mais Informações”, “Sub Detalhe” ou ainda um “Check” para por exemplo indicar que o item está selecionado para alguma ação.
#Dica: Procure observar outros aplicativos e seguir os conceitos padrões de cada sistema operacional, pois o principal fator para que uma aplicação tenha sucesso é: Usabilidade. Lembre-se que o usuário já está acostumado com certos comportamentos nos apps que já utiliza no dia-a-dia.
Configuraremos somente os itens de nosso interesse. Clique no ListBoxItemGroupHeader1 e configure como a seguir:
- Name: lstgrpListas
- Text: Cadastros
O segundo grupo, modifiquei como a seguir:
- Name: lstgrpConfig
- Text: Configurações
Agora configure o TListBoxItem1 como a seguir:
- Name: lstitTitulos
- Text: Títulos
- ItemData > Acessory: More
Repita os passos anteriores para configurar os demais itens de menu. Nosso menu final terá que ficar semelhante a Figura 7. Os Names, respectivamente, são:
- lstitTitulos
- lstitUsuarios
- lstitTitulosAlugados
- lstitLogin
Figura 7. Menu final
Observe que não colocamos todos os itens de menu na tela nesse primeiro momento. Vamos “comer o boi por partes” como dizem meus conterrâneos. Muito bom! Nossa mecânica para carregar cada Form será a seguinte:
- Para cada Lista, teremos um TForm com suas próprias funcionalidades, barras de navegação, etc;
- Não utilizaremos Show ou ShowModal, ao contrário. Criaremos o TForm no momento oportuno e carregaremos ele dentro do TLayout principal em nosso frmMain utilizando um AddObject. Dessa forma temos controle total sobre todos os forms abertos.
Por conta do segundo item que colocamos o menu (ListBox) e o layout (TLayout) dentro do formulário e não um dentro do outro como mencionado anteriormente. Nosso lytMain será um mero espectador, receberá dentro dele todos os objetos (Forms) que precisarmos navegar.
Para ter certeza que fez as configurações corretas, seu projeto deverá se parecer com a Figura 8 que se refere a caixa Struture do Delphi.
Figura 8. Caixa Structure
Primeira codificação
Perfeito até aqui e sei que estão eufóricos para codificar tudo. Então mãos a obra. Primeiro criaremos métodos para mostrar e ocultar o menu. Para isso, teremos que adicionar alguns elementos visuais ao formulário para termos uma aparência mais interessante.
Adicione ao formulário 2 (dois) novos componentes. 1 TFloatAnimation e 1 TRectangle. Eles devem ficar DENTRO do lytMain. O componente de animação deve receber o Name = AnimateDrawer. Já o TRectangle precisa ser configurado como a seguir:
- Name: recBackground
- Opacity: 0,5
- Fill.Color : Black
- PropertyName: Position.X
Essas configurações darão um aspecto mais profissional. Se desejar conferir a estrutura dos componentes novos, observe a Figura 9.
Figura 9. Aspecto final do menu
Vamos ao código dos métodos agora. Crie duas novas Procedures na seção Private do Form como na Listagem 1:
Listagem 1. Código dos novos métodos
procedure HideMenu; procedure ShowMenu;
Pressione Ctrl + Shift + C para criar o escopo de cada método e vamos ao código de cada um conforme a Listagem 2.
Listagem 2. Código dos métodos criados para Mostrar e Ocultar o Menu
procedure TfrmMain.HideMenu; begin //Posiciona o ListBox de menu fora da visão lstMnuMain.AnimateFloat('Position.X', -Self.ClientWidth); AnimateDrawer.StartValue := Self.ClientWidth - 40; AnimateDrawer.StopValue := 0; AnimateDrawer.Start; end; procedure TfrmMain.ShowMenu; begin AnimateDrawer.StartValue := 0; AnimateDrawer.StopValue := Self.ClientWidth - C_MnuEspaco; AnimateDrawer.Start; //Reposiciona o menu principal lstMnuMain.AnimateFloat('Position.X', 0); //Mostra o retângulo preto sobre a lista ativa ShowBackground(Self.lytMain, CancelMenu);</pre> <pre>end;
No primeiro método, HideMenu, posicionamos o ListBox do menu para fora da área de visualização utilizando uma animação através do método AnimateFloat. Esse é método é um dos que mais gosto de usar. É bem simples e praticamente todos os objetos Firemonkey possuem. Basta passar a propriedade que se deseja animar no primeiro parâmetro e o novo valor no segundo parâmetro. Nesse caso usamos Position.X com o valor -Self.ClientWidth, que fará o componente se descolar para a esquerda.
Em seguida animamos o layout usando o nosso componente TFloadAnimation. O código ao meu ver dispensa comentários assim como o método ShowMenu que é exatamente o inverso. Apenas observe que reposicionamos o ListBox na posição 0 (Zero).
Teremos ainda que criar outros métodos que nos ajudarão a controlar melhor o menu. Retorne as seções Private e Public do form e adicione os novos métodos conforme a Listagem 3.
Listagem 3. Outros métodos de controle do menu
private { Private declarations } procedure HideMenu; procedure ShowMenu; procedure CancelMenu(Sender: TObject); public { Public declarations } procedure ShowHideMenu; procedure ShowForm(AObject: TFmxObject); procedure ShowBackground(AParent: TFmxObject; AOnClick: TNotifyEvent = nil); procedure HideBackground; end;
Vamos as explicações:
- CancelMenu: Será necessário para esconder o retângulo opaco da tela e ocultar o menu;
- ShowHideMenu: Controla a visibilidade do menu;
- ShowForm: Indicaremos ao formulário Main quem deverá estar visível ou invisível;
- ShowBackground e HidBackground: Responsáveis por mostrar e ocultar o retângulo;
Pressione Ctrl + Shift + C para criação dos escopos e codifique como na Listagem 4.
Listagem 4. Métodos de controle do menu
procedure TfrmMain.CancelMenu(Sender: TObject); begin HideBackground; ShowHideMenu; end; procedure TfrmMain.ShowHideMenu; var Position : single; begin {Verifica a posição atual do menu e mostra ou oculta conforme necessário} Position := Self.ClientWidth - 40; case Self.lytMain.Position.X = Position of true : HideMenu; false : ShowMenu; end; end; procedure TfrmMain.ShowForm(AObject: TFmxObject); var I : Integer; begin HideBackground; for I := 0 to Pred(Self.lytMain.Children.Count) do TControl(Self.lytMain.Children[I]).Visible := TControl(Self.lytMain.Children[I]) = TControl(AObject); end; procedure TfrmMain.ShowBackground(AParent: TFmxObject; AOnClick: TNotifyEvent); begin //Atualiza o evento OnClick do retâgulo com a ação enviada por parâmetro. ///Isso fará com que saibamos a tela (ou ação) que deve ser mostrada ao clicar no retângulo recBackground.OnClick := AOnClick; recBackground.Parent := AParent; recBackground.BringToFront; //Modifica a transparência do retângulo e anima a transparência recBackground.Opacity := 0; recBackground.Visible := True; recBackground.AnimateFloat('opacity', 0.5, 0.1); end; procedure TfrmMain.HideBackground; begin recBackground.AnimateFloat('opacity', 0, 0.1); recBackground.Visible := False; end;
Vamos as explicações de cada método iniciando por CancelMenu. Esse método apenas chama HideBackground e ShowHideMenu forçando o retângulo opaco desaparecer e checando se o menu está aberto ou fechado para saber para onde temos que ir.
Em seguida ShowHideMenu. Através da variável Position conseguimos detectar qual o posicionamento do Menu (nosso ListBox, lembre-se). A variável recebe a largura da tela atual, ou seja, funcionará tanto com celulares quanto com tablets e na horizontal ou vertical. E subtraímos 40 px para evitar que a tela (listagem) atual suma completamente da visão do usuário. Com base na posição do menu, decidimos se o mostramos ou ocultamos.
ShowForm será responsável por receber o objeto (Form, Layout, TabControl) alvo e deixa-lo visível para o usuário. A ideia é simples. Quando codificarmos o OnClick de cada Item de Menu, faremos um AddObject dentro do nosso lytMain, em seguida chamamos ShowForm para ocultar todos os outros formulários e mostrarmos somente o atual. Isso é necessário, pois nosso ListBox está configurado como como Transparente. Se deixarmos visíveis os demais forms, corremos o risco de sobrepor as telas.
Por fim ShowBackGround e HideBackGround. No primeiro método, recebemos o Parent do objeto que está sendo carregado, para que o retângulo opaco fique sobre ele, assim teremos um aspecto “esmaecido” do form quando o menu estiver aberto. Também recebemos um evento OnClick caso desejarmos que ao clicar no retângulo algo aconteça. Por fim trazemos ele para frente e configuramos sua opacidade, visibilidade e a animação para aparecer. Reparem que estou usando novamente o método AnimateFloat (dessa vez no retângulo) passando como parâmetro a propriedade ‘opacity’ e os valores 0.5 e 0.1 nos parâmetros seguintes.
O 0.5 é o novo valor da opacidade, para deixa-lo levemente transparente. O 0.1 é o tempo que levará para a animação ocorrer.
Criando o segundo FORM e testando o menu
A essa altura do campeonato, provavelmente conseguiremos compilar normalmente nossa aplicação sem problemas. Então, agora vamos criar um segundo formulário para testar se nosso menu e nossa mecânica está funcionando perfeitamente.
Crie um novo form usando File > New > Firemonkey Mobile Form – Delphi e marque a opção HD FireMonkey Form. Por fim clique em Ok, para finalizar (Figuras 10 e 11). Agora temos um segundo formulário que será usando para nossa Lista de Títulos.
Figura 10. Criação do novo Form
Figura 11. Confirmação do novo Form
Vamos apenas configurar as propriedades mais básicas e o layout principal do formulário. Na Parte II do post faremos a prototipação da janela para evitar que esse post fique ainda maior.
Primeiro adicione um ToolBar no formulário e mude sua propriedade Name para toolTitulos. Inclua em seguida um TLayout ao formulário e chame-o de lytTitulos. Também configure-o para que fique com alinhamento Client (Align = Client). Nós carregaremos o lytTitulos dentro do lytMain no formulário principal.
Dentro do TLayout adicione um TabControl e configure suas propriedades como a seguir:
- Name: tabctrlTitulos
- TabPosition: Bottom
Clique com o botão direito no TabControl e adicione uma nova aba usando o item Add TTabItem. Nessa TabItem (que chamamos de Aba) colocaremos nossos controles para acesso a base de dados. Por enquanto vamos adicionar apenas um TLabel com alinhamento Client e o Text igual a “Listagem de Títulos”. Modifique também a propriedade TextSettings.HorzAlign para Center, apenas para sinalizar quando carregarmos essa janela no dispositivo ou emulador.
Para fechar, adicione um TSpeedButton dentro da ToolBar. Ele será nosso botão voltar. Configure-o como a seguir:
- Name: spbBack
- StyleLookup: detailstoolbutton
- Align: Left
- Margins.Left: 8
Teremos então uma aparência semelhante a imagem da Figura 12.
Figura 12. Aparência do formulário Títulos
A única codificação por hora nesse Form é fazer a chamada ao método ShowHideMenu do formulário principal. Isso mesmo! Nós vamos fazer um Use Unit do formulário principal em nossa Listagem de Títulos. Clique em File > Use Unit e adicione a unit UntMain na seção Implementation do form.
Em seguida clique duas vezes no único botão dessa tela e adicione a linha de código a seguir:
frmMain.ShowHideMenu;
Fazendo isso, nós chamamos o método ShowHideMenu que se encarregará de mostrar o menu novamente para que o usuário possa entrar em outra janela.
Uma última alteração no código-fonte da janela, retire a declaração da variável com a instância do form, não precisaremos dela. Localize a seção implementation e apague as linhas como a seguir:
var frmTitulos: TfrmTitulos;
Retornamos agora para o formulário principal para fazer a as devidas chamadas e abrir a nossa tela de títulos. Acesse File > Use Unit e adicione o formulário de títulos a seção interface do form principal. Agora selecione o lstitemTitulos e adicione o código da Listagem 5 ao evento OnClick.
Listagem 5. Código do evento OnClick para abertura da tela Listagem de Títulos
if not Assigned(FTitulos) then FTitulos := TfrmTitulos.Create(Self); {Adiciona o Layout de Pedidos ao Layout Principal que controla tudo} lytMain.AddObject(FTitulos.lytTitulos); {Deixa todos os layouts invisíveis e deixa o layout alvo visível} ShowForm(FTitulos.lytTitulos); if Sender <> Self then ShowHideMenu;
O que estamos fazendo aqui é bem simples na verdade. Primeiro verificamos se há alguma instância do formulário de títulos na memória. Note que usamos uma variável FTitulos para isso e logo em seguida criamos o Form frmTitulos. A variáveis FTitulos precisa ser declarada na seção Private do form principal, como abaixo:
... private FTitulos: TfrmTitlos; ...
Na seqüência adicionamos o TLayout lytTitulos (Form Titulos) ao TLayout lytMain do formulário principal. Por fim chamamos ShowForm para fazer com que o form se torne visível. A última instrução evita que o menu apareça caso quem esteja chamando o método seja o próprio form principal.
Estaria pronto para testar nesse momento, mas ainda vamos fazer umas configurações. Lembram-se que nosso formulário de títulos será aberto assim que a app inicializar? Pois bem, teremos que codificar então o evento OnCreate do form principal. Para isso selecione o Form e clique duas vezes no evento OnCreate e codifique como na Listagem 6.
Listagem 6. OnCreate do form principal
procedure TfrmMain.FormCreate(Sender: TObject); begin {Layout Escuro Global} recBackground.Visible := False; recBackground.Align := TAlignLayout.Contents; {Modifica a largura do ListBox para a mesma do formulário, pois o mesmo está como Align = None} lstMnuMain.Width := Self.ClientWidth; lstMnuMain.Position.X := -Self.ClientWidth; //Traz para frente o layout principal evitando sobreposição de listas lytMain.BringToFront; lstitTitulosClick(Sender); end;
Precisamos de algumas personalizações aqui. Primeiro nós deixamos o retângulo invisível e mudamos seu alinhamento para Contents, ou seja, ao conteúdo, equivalente a opção Client.
#Dica: A diferença entre os alinhamentos Client e Contents, é que Contents encobre também as barra de status do aparelho, normalmente visível na parte superior.
Em seguida ajustamos o menu principal e trazemos o layout para frente de todos os objetos. Por fim, chamamos o método lstitTitulosClick para forçar a abertura do formulário Listagem de Títulos.
E a última codificação acontece no evento OnClose do formulário principal. Forçamos a liberação da instância do formulário de títulos caso esteja aberto.
if Assigned(FTitulos) then FTitulos.DisposeOf;
Atenção para o método DisposeOf. Não utilize em Mobile o método Free ou FreeAndNil, pois acabam entrando na fila do ARC (Gerenciamento de Memória do dispositivo). O DisposeOf força o FREE da variável imediatamente. Em outras palavras, variáveis ou objetos devem ser liberados de memória usando esse método.
Testando a app
É óbvio que depois de chegarmos até aqui, estamos curiosos para testar a aplicação. Então é hora de contar um segredo. Não exatamente um segredo, mas uma dica útil. Não vamos perder tempo compilando para iOS ou Android, ou ainda nos simuladores/emuladores. Vamos testar direto no Windows, pois todas as funcionalidades até aqui codificadas funcionam perfeitamente no Windows.
Para isso, acesse o Project Manager à sua esquerda (caso não tenha mudado as configurações do Delphi) e clique com o botão direito em cima de Target Platforms. Clique em Add Platform e escolha Win32 na janela que aparece (Figuras 13 e 14).
Figura 13. Adição de plataforma
Figura 14. Plataforma Win32
Agora basta clicar duas vezes na plataforma e executar a aplicação.
#Dica: Caso não precise debugar a aplicação, selecione Release em Build Configurations, pois é mais rápido o deploy, inclusive dos aparelhos.
Se tudo correr bem, teremos telas semelhantes as figuras seguintes:
Conclusão
Assim como mencionado desde o início, existem milhares de maneiras diferentes de criar layouts e navegação em uma app Mobile. Essa é apenas uma delas. Vimos nesse post como criar nosso primeiro menu no estilo Facebook e como interagir com mais de um form na mesma aplicação.
No próximo post, veremos como prototipar a aplicação. Criaremos uma lista de títulos utilizando LiveBindings e o componente PrototypeBindSource assim como o uso de DataModule.
A discussão referente a esse post estará disponível nos comentários ao final desse post e também na comunidade Delphi Experts no Facebook através do link:
https://www.facebook.com/groups/DelphiExperts/
Acesse, faça seus comentários e tire suas dúvidas.
Uma atualização. Existe uma constante mencionada no método ShowMenu, C_MnuEspaco. Troquem ela pelo valor 40. Esse é o espaço que a listagem ficará afastada quando o menu estiver aberto.
procedure TfrmMain.ShowMenu; begin AnimateDrawer.StartValue := 0; AnimateDrawer.StopValue := Self.ClientWidth - 40; AnimateDrawer.Start; //Reposiciona o menu principal lstMnuMain.AnimateFloat('Position.X', 0); //Mostra o retângulo preto sobre a lista ativa ShowBackground(Self.lytMain, CancelMenu); end;
O código-fonte desse exemplo pode ser baixado em:
https://bitbucket.org/tdevrocks/tutorial-criando-meu-app-step-by-step
Author: Adriano Santos
5 Comentários
Comments are closed.
[…] #1 Building A Basic Layout Create the app; Create the initial layout; Develop basic navigation between tabs; Develop basic navigation between forms application. […]
[…] primeira parte de nosso Tutorial: Criando meu app step-by-step cujo o foco foi o desenvolvimento completo de um aplicativo para iOS e Android, nós mostramos uma […]
[…] Tutorial: Criando meu app step-by-step – Parte I […]
[…] Tutorial: Criando meu app step-by-step – Parte I – 3.000 visualizações […]
[…] para nossos vídeos estão disponíveis no site, assim você os encontrará facilmente, tais como: Criando meu app step-by-step e Criando aplicativos móveis com […]