artigos - the club · password teste123 (senha ficticia) database apenas o nome da base de dados...

16
Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx 1 de 16 23/12/2015 16:37

Upload: others

Post on 16-Sep-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

1 de 16 23/12/2015 16:37

Page 2: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Você que gosta de aplicações Android, desenvolve, chama a atenção, quando vê uma app, com umdesign legal, compartilhando informações em redes sociais e se pergunta: como posso fazer isso em minhaaplicação?

Vou tentar mostrar nesse artigo, algumas dicas interessantes para aplicativos Android.Compartilhando em redes sociaisQuase todos aplicativos Android, tem a opção de compartilhar informações do aplicativo com redes

sociais. Isso é quase uma “febre” hoje em dia. Mas como desenvolver a opção de compartilhar textos daminha app com redes sociais?

Vamos ao exemplo. Crie um projeto no Android Studio (escolha o tipo de projeto que desejar). Notemplate que você criou, vá no menu que já existe na pasta menu, dentro de res. Adicione um novo item:

<item android:id="@+id/action_shared" android:title="Compartilhar" app:actionProviderClass="android.support.v7.widget.ShareActionProvider" app:showAsAction="ifRoom" />

Note que existe uma diferença, em relação aos itens de menu, temos uma ProviderClass do tipoShareActionProvider. Ela será a responsável por compartilhar o que queremos. Não precisamos indicar umícone para o menu, o Android faz isso, colocando o ícone padrão de compartilhamento (Figura 1).

Figura 1. Ícone padrão do compartilhamento do Android

Agora, vamos acessar o método onCreateOptionsMenu para codificarmos o botão para afuncionalidade que desejamos. Veja o código da Listagem 1.

Listagem 1. Código para o botão de compartilhamento private ShareActionProvider mActionProvider;

...MenuItem shared = menu.findItem(R.id.action_shared);mActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shared);

Intent i = new Intent(Intent.ACTION_SEND);i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

i.setType("text/plain");i.putExtra(Intent.EXTRA_TEXT, "Teste de compartilhamento de texto via Android");mActionProvider.setShareIntent(i);…

Criamos uma variável no escopo da classe, do tipo SharedActionProvider. No método, pegamos oitem do menu para configurar o mesmo. Configuramos um Intent com as opções referente a texto (setType)e o valor que vamos compartilhar (putExtra).Rode a aplicação e veja na Figura 2, como fica o menu quando clicamos no mesmo.

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

2 de 16 23/12/2015 16:37

Page 3: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Figura 2. Menu de compartilhamentoNota: as quantidade de opções de compartilhamento dependerá das apps instaladas em seu device.Ao escolher, o aplicativo escolhido é aberto e podemos ver o texto a ser compartilhado (Figura 3).

Figura 3. Compartilhando o texto no Twitter

O botão mantém um “histórico” do último compartilhamento (Figura 4). Facilidade paracompartilhamento em aplicativos mais comuns.

Figura 4. Histórico de compartilhamentoLayoutAlguns desenvolvedores novatos do Android (o que foi meu caso), “penam” para criar layouts um

pouco mais complexos, seja de cadastro ou apenas exibição de dados. Amos conhecer os cincos tipos delayout:

Linear Layout: controles ficam organizados em linha ou em coluna. Layout padrão em qualquerprojeto criado no Android.

Table Layout: controles podem ficar organizados em forma tabular com linhas e colunas (comouma tabela, semelhante a aplicações Web).

Relative Layout: controles ficam organizados em relação a outro ou do pai. Nesse podemoscolocar controles no “formulário” onde queremos. É o layout mais utilizado pelos desenvolvedores.

Absolute Layout: posiciona os controles absolutamente. Deve ser usado com cautela, pois

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

3 de 16 23/12/2015 16:37

Page 4: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

controles podem ser sobrepor e de acordo com a resolução do device, não ter o efeito desejado.Frame Layout: permite a alteração dinâmica dos controles. Muito utilizado para Fragments.

Nota: dentro de um layout, podemos ter outros layouts. Exemplo, em uma tela de listagem, a partesuperior onde temos uma pesquisa customizada, seus controles podem ficar em um Relative Layout,enquanto a listagem em si, pode ficar em um Linear Layout.

Quando temos uma tela com vários controles, em alguns casos, precisamos agrupar os mesmos paraque não fique um visual muito poluído. O que vou mostrar é uma tela “dividida” usando dois Linear Layoutpara entendermos como dividir a tela.O código a seguir, criar dois “conteiners” em uma tela com um Linear usando orientarion = vertical.

<LinearLayout android:background="#00FF00" android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" /><LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" />

Coloquei uma cor para podermos diferenciar os layouts (Figura 5).

Figura 5. Dois layouts dentro de um Linear Layout

Caso queira mudar a orientação do Linear “pai”, o efeito é bem interessante, como vemos na Figura6.

Figura 6. Orientação diferente, da um efeito interessante na tela

Estamos usando Layouts, mas podemos usar qualquer controle para criar layouts complexos e deacordo com nossa necessidade. Caso seja necessário um “tamanho” maior para um dos layouts, bastatrabalhar com layout_weight maior que 1.

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

4 de 16 23/12/2015 16:37

Page 5: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Você deve ponderar para que não ajam distorções.Você também pode simular um cabeçalho e rodapé em uma tela:

<LinearLayout android:background="#00FF00" android:layout_height="50dp" android:layout_width="match_parent" /> <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_weight="1" /> <LinearLayout android:background="#0000FF" android:layout_height="50dp" android:layout_width="match_parent" />

No “centro”, poderíamos ter um Frame Layout e carregar Fragments de acordo com nossanecessidade, semelhante a um wizard. Veja na Figura 7 o exemplo.

Figura 7. Criando cabeçalho e rodapé com layoutsConclusão

Vimos nesse artigo, algumas dicas legais para aplicarmos em aplicações Android. Ocompartilhamento de textos, imagens é algo rotineiro para qualquer aplicação. Construir aplicações comlayouts complexos também está no dia a dia do desenvolvedor Android, e espero ter ajudado passandodicas simples, mas que vão ajudar na criação de telas mais complexas.Um grande abraço a todos e sucesso em seus projetos.

Sobre o Autor

Luciano Pimenta (NOVO DOMINIO: www.lucianopimenta.com) é desenvolvedorDelphi/C# para aplicações Web com ASP.NET, Windows com Win32 e Windows Formscom .NET. Palestrante da 4ª edição da Borland Conference (BorCon) e da 1ª DelphiConference. Aventurando-se no mundo Mobile com Android. É MVP Embarcadero, grupode profissionais que ajudam a divulgar o Delphi no mundo. Atualmente é desenvolvedorda LabTrans em Florianópolis-SC.

E-mail: www.lucianopimenta.com

Caro amigo leitor,Neste artigo irei tratar de um assunto utilizado na distribuição de praticamente todo sistema, o uso

de arquivos de configuração do tipo .INI. Usarei como ferramenta o Delphi XE 5 e como conexão de dados oFiredac. O Firedac é uma biblioteca de acesso universal a dados a diferentes tipos de Bancos de Dados.(Este artigo será com base no SQL Server e Firebird). Podemos dizer que o FireDAC possui uma engineotimizada para acesso a dados e disponível a partir do Delphi XE 3. Para maiores informações recomendo aleitura do artigo do mês 06/2013 chamado “Firedac” de nosso colunista Luciano Pimenta. Iremos criar umaclasse para a leitura do arquivo .INI para atribuirmos os parâmetros de conexão para nosso componente“TFDConnection” dentro de um “DataModule”.

Criando o Arquivo .INI

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

5 de 16 23/12/2015 16:37

Page 6: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

O formato de arquivo INI é um padrão informal para arquivos de configuração paraalgumas plataformas ou software. Arquivos INI são arquivos de texto simples com uma estrutura básicacomposta de "seções" e "propriedades”. A partir destas configurações conseguimos utilizá-la dentro dodelphi com uma enorme facilidade.

Crie uma pasta para organizar o exemplo e dentro da mesma, crie um arquivo vazio com estensãoINI. Ver Imagem 01.

Figura 01: Criando o Arquivo INI.

Iremos criar duas seções, sendo uma para o Banco FireBird e outro para o SQL Server com algumaspropriedades. Ver Imagem 02.

Figura 02: Propriedades.Configurações do Firebird

Podemos conferir as configurações detalhadas na Tabela 01.

[FIREBIRD] Nome da seção, indicando o Banco dedados FireBird.

Server Servidor onde está armazenado o Banco deDados. (No meu caso defini Localhost, quesignifica que está no mesmo computadoronde se encontra a aplicação)

User SYSDBA (Usuário Padrão)Password Masterkey (Senha Padrão)DataBase Caminho onde o Banco está localizado.

Tabela 01.

Configurações do SQL Server

Podemos conferir as configurações detalhadas na Tabela 02.

[SQLSERVER] Nome da seção, indicando o Banco dedados SQL Server.

Server Servidor onde está armazenado o Banco deDados. (No meu caso defini um servidorficticio)

User Thiago (usuário ficticio)

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

6 de 16 23/12/2015 16:37

Page 7: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Password Teste123 (senha ficticia)DataBase Apenas o nome da Base de Dados

Tabela 02.Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo desenvolvido em

Delphi, ou seja, teremos o executável exatamente na mesma pasta onde está localizado o arquivo deconfiguração.

Criando a classe para leitura do arquivo INI

Para quem estiver utilizando a versão do Delphi XE 5, crie um projeto do início adicionado ao projetouma Unit vazia.

unit UnFuncoes;interface

Declaramos algumas “units” necessárias na cláusula “Uses”.

uses IniFiles, IWSystem, SysUtils;

Na declaração da Classe teremos apenas o método estático “LerIni”, contendo três parâmetros,sendo os dois primeiros indicando a seção/propriedade e o último um valor padrão vazio que utilizaremosno método “ReadString” da classe “TiniFile”.

type TFuncoes = class Public class function LerIni(Chave1, Chave2: String; ValorPadrao: String = ''): String;static; end;implementationclass function TFuncoes.LerIni(Chave1, Chave2: String; ValorPadrao: String = ''):String;var Arquivo: String; FileIni: TIniFile;begin Arquivo := gsAppPath + gsAppName + '.ini'; result := ValorPadrao; try FileIni := TIniFile.Create(Arquivo); if FileExists(Arquivo) then result := FileIni.ReadString(Chave1, Chave2, ValorPadrao); finally FreeAndNil(FileIni) end;

end;

end.

Este método é bem simples, a variável “Arquivo” receberá o Path absoluto da aplicação, com oauxílio das funções gsAppPath (para recuperar o Path) concatenando com o nome do arquivo“configuracao.ini”. Já a variável “FileIni” criará uma instância de um objeto encapsulando no construtor oarquivo INI criado anteriormente e por final usaremos o método “ReadString” para a seção/propriedadeindicada retornando o valor.

Carregando os Parâmetros de Conexão

Usaremos um DataModule para organização dos componentes utilizados. Na palheta “FireDAC”Adicione dois TFDConnection (FDConnectionFirebird e FDConnectionSQLServer). Na “FIreDAC Links”adicionaremos mais dois componentes, sendo o “TFDPhisMSSQLDriverLink e o TFDPhisFBDriverLink”respectivamente para os bancos SQLServer e Firebird. Por último adicione um “FDGUIxWaitCursor” da“FireDAC UI”.

Importante: Todos estes componentes são necessários para o funcionamento de uma aplicaçãoFIREDAC. Para maiores detalhes sobre eles recomendo a leitura do artigo supracitado.

Podemos conferir maiores detalhes na Imagem 03.

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

7 de 16 23/12/2015 16:37

Page 8: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Figura 03. Configurando os componentes necessários para Conexão.

unit UnConexao;…

Usaremos as units abaixo, sendo a primeira para acesso a classe criada e a segunda para termosacesso ao método ShowMessage.

uses unFuncoes, Dialogs;procedure TDataModule1.DataModuleCreate(Sender: TObject);begin try with FDConnectionFirebird do begin Params.Clear; Params.Values['DriverID'] := 'FB'; Params.Values['Server'] := TFuncoes.LerIni('FIREBIRD','Server'); Params.Values['Database'] := TFuncoes.LerIni('FIREBIRD','Database'); Params.Values['User_name'] := TFuncoes.LerIni('FIREBIRD','User'); Params.Values['Password'] := TFuncoes.LerIni('FIREBIRD','Password'); Connected := True; end; except ShowMessage('Ocorreu uma Falha na configuração no Banco Firebird!'); end;

try with FDConnectionSQLServer do begin Params.Clear; Params.Values['DriverID'] := 'MSSQL'; Params.Values['Server'] := TFuncoes.LerIni('SQLSERVER','Server'); Params.Values['Database'] := TFuncoes.LerIni('SQLSERVER','Database'); Params.Values['User_name'] := TFuncoes.LerIni('SQLSERVER','User'); Params.Values['Password'] := TFuncoes.LerIni('SQLSERVER','Password'); Connected := True; end; except ShowMessage('Ocorreu uma Falha na configuração no Banco SQL Server!'); end;end;end.

No evento OnCreate do DataModule poderemos carregar todas as configurações necessárias.Usaremos um bloco try/Except junto com o Método “Params.values” para alimentarmos nossoscomponentes.

Tanto para o Firebird quanto para o SQl Server utilizaremos os parâmetros “Server”, “DataBase”,“User_name” e “Password”. Divergindo apenas o valor “DriverID”.

Prontinho, caso não ocorra nenhum erro de configuração poderemos partir para a utilização deste“Datamodule” nos nossos formulários, mas aí fica para o próximo artigo.

Conclusões

Pudemos aprender neste artigo o uso correto de arquivos de configuração em parceria com a

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

8 de 16 23/12/2015 16:37

Page 9: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Biblioteca de componentes FireDAC. Fica aí a dica para quem deseja implementar este recursos em seussistemas.

Um forte abraço e até o mês que vem!

Sobre o Autor

Thiago Cavalheiro Montebugnoli adora aprender novas tecnologias. Formado pelaFaculdade de Tecnologia de Botucatu – SP (FATEC), já desenvolveu softwares utilizandoa plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Comoexperiências profissionais mais recentes, possui em seu currículo sua atuação no Centrode Processamento de Dados da Prefeitura Municipal de Itaí-SP e atualmente compõe aequipe da Coordenadoria Tecnologia da Informação no IFSP – Instituto Federal doEstado de São Paulo em Avaré. Além disso, é colunista mensal da Revista The ClubMegazine e é consultor Técnico do The Club. Possui as seguintes certificações: MCP -Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD -Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer.

E-mail: [email protected]

Recapitulando

Como vimos na nossa matéria anterior, o Polymer é uma biblioteca JavaScript mantida pelo Googleque auxilia na criação de Web Components, ou seja, ajuda a criar suas próprias tags HTML. Isso torna seucódigo reutilizável e facilitando a manutenção, tudo isso independente de plataforma.

Hoje nós iremos aprender um pouco mais sobre os eventos presentes nessa incrível biblioteca.

O que são eventos?

Os eventos são funções que são ativadas a partir de um determinado gatilho que pode serconfigurado por você. Aqui está alguns exemplos de eventos:

Um botão é clicadoUm campo em um formulário foi alteradoA página terminou de carregarO usuário tentou sair da página aberta

Configurando o event listener

O event listener é uma coleção com os eventos e suas respectivas funções que serão executadas.A variável listeners é a responsável por mapear os eventos do elemento. Sua sintaxe é bastante

simples:

listeners: {‘click’: ‘onClickEvent’, ‘focus’: ’onFocusEvent’, ‘evento’: ‘nomeDaFuncao’}

Existem dezenas de eventos pré-programados no HTML e no Java Script, elas são dividas entrediversas categorias, como os eventos específicos para formulários, os genéricos, entre outros. A versãocinco do HTML trouxe muitas novidades em relação aos eventos dando suporte inclusive aos eventosrelacionados a telas sensíveis ao toque e aos conteúdos de mídia.

Outra informação importante é que você pode adicionar um evento para qualquer elemento dentrode seu componente, para isso basta usar a sintaxe elementoId.nomeDoEvento, veja um exemplo a seguir:

<link rel=“import” href=“../../bower_components/polymer/polymer.html”><dom-module id=“hello-world”> <template>

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

9 de 16 23/12/2015 16:37

Page 10: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

<p>Hello {{nome}}</p> <button id=“vip”>Requisitar acesso VIP</button> <template> </script> Polymer({ is: ‘hello-world’, properties: { nome: { type: String, value: ‘Ricardo’ } }, listeners: { ‘click’: ‘clickComum’, ‘vip.click’: ‘clickVip’ // O evento será acionado somente quandoclicarmos no elemento com id igual a vip }, clickComum: function(e) { alert(“Obrigado por clicar!”); }, clickVip: function(e) { alert(“Você requisitou acesso VIP”); } }); </script></dom-module>

Outra forma muito comum de configurar eventos é diretamente no DOM local, ou seja utilizar aspropriedades on-event direto nas tags HTML de seu componente. Esse meio é interessante pois vocêelimina a necessidade de declarar um id para cada elemento. Confira um exemplo:

<link rel=“import” href=“../../bower_components/polymer/polymer.html”><dom-module id=“hello-world”> <template> <p>Hello{{nome}]</p> <button on-click=“clickVip”>Requisitar acesso VIP</button> <template> </script> Polymer({ is: ‘hello-world', properties: { nome: { type: String, value: ‘Ricardo’ } }, clickComum: function(e) { alert(“Obrigado por clicar!”); }, clickVip: function() { alert(“Você requisitou acesso VIP”); } }); </script></dom-module>

Dica importante: neste caso, como o nome do evento é um atributo HTML o nome é sempreconvertido para letras minúsculas, já que os nomes de atributos no HTML não diferem entre letrasmaiúsculas e minúsculas (case insensitive).

Eventos customizados

Assim como quase tudo no Polymer, você pode criar seus próprios eventos e ativá-los de fora de seucomponente. Para isso utilizamos o método fire. Uma observação muito importante é que é o método fireaceita passar argumentos dentro do seu evento.

Vejamos um exemplo de como fazer um evento personalizado:

<!-- Arquivo: ./elements/hello-world/hello-world.html --><link rel=“import” href=“../../bower_components/polymer/polymer.html”>

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

10 de 16 23/12/2015 16:37

Page 11: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

<dom-module id=“hello-world”> <template> <p>Hello{{nome}]</p> <button on-click=“clickVip”>Requisitar acesso VIP</button> <template> </script> Polymer({ is: ‘hello-world', clickVip: function(e, detail) { this.fire(‘acesso’, {vip: true}); } }); </script></dom-module>

E agora nosso arquivo que irá conter o nosso elemento e “escutará” pelo evento “acesso”:

<!-- Arquivo: ./index.html --><link rel=”import” href=”./elements/hello-world/hello-world.html” />

<!-- Inserimos nosso componente --><hello-world></hello-world>

<!-- Adicionamos um event listener para o evento ‘acesso’, ou seja, o código seráexecutado somente quando o evento for disparado --><script> document.querySelector(‘hello-world’).addEventListener(‘acesso’, function(e){ console.log(e.detail.vip); // irá retornar true });</script>

Eventos para gestos

O Polymer possui alguns eventos customizados que são ativados sempre que determinados “gestos”são realizados. Estes eventos são ativados tanto em movimentos com o mouse quanto em movimentos comtoque, então é sempre recomendado utilizar estes eventos ao invés dos tradicionais mouse- ou os eventosespecíficos para o toque. Por exemplo, é recomendado usar o tap ao invés de click, pois assim você garanteque seu evento será disparado com um toque na tela ou com um clique do mouse.

A seguir preparei uma listagem com os eventos por gestos suportados pelo Polymer com umapequena descrição de cada evento.

Evento Descriçãodown Dedo ou botão pressionadoup Dedo ou botão retirado da tela ou clique

do mouse soltotap Eventos down e up seguidos – acionado

quando se clica no elemento ou quandovocê toca com o dedo e retirarapidamente.

track Evento acionado quando o dedo ou botãoé deslizado enquanto o dedo estápressionado - um exemplo de quandoesse evento é acionado é quando rolamosuma página para baixo no celular.

Um exemplo bem simples dos eventos para gestos:

<dom-module id=”track-test”> <template> <div id=”drag” on-track=”handleTrack”>{{mensagem}}</div> </template> <script> Polymer({ is: 'track-test',

handleTrack: function(e) {

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

11 de 16 23/12/2015 16:37

Page 12: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

switch(e.details.state) { case 'start': this.mensagem: 'Track iniciado'; break; case 'track': this.mensagem: 'Track em progresso... coordenadas: ' +e.detail.x + ', ' + e.detail.y; break; case 'end': this.mensagem: 'Track finalizado'; break; } } });

</script></dom-module>

O mesmo exemplo pode ser reescrito utilizando os listeners, mas nesse caso todo o elemento irá“ouvir” o evento:

<dom-module id=”track-test”> <template> {{mensagem}} </template> <script> Polymer({ is: 'track-test',

listerners: { track: 'handleTrack' },

handleTrack: function(e) { switch(e.details.state) { case 'start': this.mensagem: 'Track iniciado'; break; case 'track': this.mensagem: 'Track em progresso... coordenadas: ' +e.detail.x + ', ' + e.detail.y; break; case 'end': this.mensagem: 'Track finalizado'; break; } } });

</script></dom-module>

Como esses eventos são mais complexos e de uso mais específicos, eles não serão apresentadoshoje, para saber mais acesse a documentação oficial no site http://www.polymer-project.com.

Conclusão

No artigo de hoje conseguimos ter uma boa visão de como os Web Components podem se tornarainda mais poderosos quando utilizamos eventos para controlar seu comportamento e liga-los a outroscomponentes, seja através dos eventos disponíveis no HTML 5 ou no Java Script e atém mesmo criandoseus próprios eventos.Vimos também um pouco sobre os eventos para telas sensíveis ao toque e a vantagem de se utilizá-los.Bom por hoje é só, espero que tenham gostado e até a próxima!

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

12 de 16 23/12/2015 16:37

Page 13: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Sobre o Autor

Ricardo Barbosa Crivelli, mais conhecido como Rico, é formado como Bacharel emSistemas de Informação e Licenciado em Computação pela Universidade Estadual doNorte do Paraná, atualmente é Técnico em TI no Instituto Federal de São Paulo –Câmpus Avaré. Tem como especialidade a linguagem PHP e o framework Symfony,apesar de adorar trabalhar com front-end e desenvolvimento mobile e possuir ascertificações COBiT 4.1 Foundation e Delphi 2006 Developer.

E-mail: [email protected]

Sempre ao carregar ou definir atributos de algum tipo de persistência me deparo com a situação decomo podemos melhorar as coisas. Estava criando um arquivo ini de configuração com a premissa deprocessar os campos a serem lidos – e como fazer uma coisa mais profissional e mais segura, a ponto degarantir que os campos a serem carregados correspondem ao total de campos, por exemplo?

Arquivos de configuração, de layout, de parametrização, ou qualquer outro tipo desejado pelodesenvolvedor – todos já passaram pela delicada situação de ler e gerar a crítica de cada um deles, mesmode forma simples – para que todos eles pudessem ser processados e finalmente carregado seu posteriorprocessamento.

Criar tabelas, instanciando objetos de TDataSet, pode ser uma tarefa fácil e trivial para a maioriados desenvolvedores. Mas a ideia aqui é outra – é definir campos em algum mecanismo de persistência,como alternativa aos ini files, e possibilitar ao nosso aplicativo ler este conteúdo e gerar as colunasnecessárias contidas nele. E aí, como fazer isso de forma direta?

Desenvolvendo componentes herdando de TDataSet sempre é uma tarefa complicada – tratamentoscom bookmarks, ponteiros, estruturas de apoio, alocações de memória, cálculos de offset, manipulaçãoentre buffers, bookmarks, TDataSet e TField, etc – nem sempre é uma “mão na roda” e até os mais simplespodem dificultar o processo de criação e compreensão. A complexidade geralmente se resume aodesenvolvimento central deste descendente de TDataSet, e alguns fatores podem ser agilizados parareduzir o tamanho de críticas no que diz respeito a criação destes campos (objetos) do tipo TField – e é aquique o nosso artigo se inicia. Como automatizar a criação e leitura destes atributos?

Vamos discorrer neste tema, criando um componente que fará o papel de “durão”, criticando nomes,valores, tipos e obrigatoriedade de preenchimento para cada objeto de TField – pois o escopo deste nossocomponente é alimentar um objeto descendente de um TClientDataSet com base neste processamentogerado e criar os campos dinamicamente – portanto, mãos a obra !!

Primeiros passos com o componente

Para início de conversa, vamos batizar nosso componente de THVParser. Este componente já temuma funcionalidade completa de parser para instruções de select, update, insert e delete, efetuandointernamente comandos SQL com base nesta montagem e gerando resultados na forma de um objetoTClientDataSet. Em outros temas vamos abordar com mais profundidade estes recursos, mas o nosso focoatual é sobre outra utilização deste componente – que é justamente a criação personalizada de scripts,para substituir outras formas tradicionais de leitura de campos persistidas, como arquivo ini, arquivos doregistro do Windows, outros tipos de arquivos, etc;

O funcionamento pode ser resumido a isto:

O usuário define primeiramente o total de campos a serem criados;1. O usuário define os campos a serem criados;2. O componente lê estas definições e as processam, criando os campos um a um.3.

Pode parecer banal, mas já foi encontrado facilmente uma forma de gerar estes atributos de formaprofissional? O propósito é encapsular a manipulação da funcionalidade de geração de TFields, tornandoeste processo mais transparente – tanto para o desenvolvedor quanto para o usuário final – pois vários tiposde erros serão verificados no momento da execução desta rotina. Podemos validar por exemplo, se o nome“Fields” foi encontrado, se o nome “Number” também foi encontrado ou não, e por aí vai – o desenvolvedornão vai mais se preocupar com “detalhes sórdidos” exigidos para a escrita destes recursos necessários. Ouentão o componente não será forte o suficiente para prever possíveis erros de criação destes campos,impactando a criação do nosso objeto recém-instanciado TClientDataSet com base nesta nossa leitura.Por exemplo, existem várias finalidades desta implementação, como por exemplo:

Criação de banco de dados;1. Criação de arquivos de log;2. Criação de arquivos XML;3.

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

13 de 16 23/12/2015 16:37

Page 14: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Criação de arquivos JSON;4. Criação personalizada de qualquer arquivo pelo usuário, tanto temporário ou definitivo;5. Implementação de um componente herdado de um TDataSet, sobreescrevendo o procedimento

abstrato InternalInitFieldDefs dele, para prover a linkagem dos objetos do tipo TField inicialmente emsua construção.

6.

Figura 01 – Exemplo da utilização de scripts de criação de tabela com o nosso componente THVParser.

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

14 de 16 23/12/2015 16:37

Page 15: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Figura 02 – Outro exemplo de um programa demo processando scripts de criação de tabela pelo componente THVParser.

Esse programa que vamos ver agora é um simulador de criador de colunas para um banco de dados.Vai funcionar de forma bem transparente para o usuário, onde se escolhe o nome das colunas, tamanho,tipo e obrigatoriedade de cada uma delas e depois manda criar. É um bom utilitário nesse sentido. Comvários recursos embutidos (um campo que indica a posição onde o campo vai ficar, rotinas de teste onde segeram valores randômicos – testes de carga, manipulações de eventos no objeto de TDBGrid) este demovisa apenas ilustrar a implementação real do componente THVParser neste cenário, onde a praticidade éadquirida de forma bem eficiente – o desenvolvedor não precisa se preocupar mais com nenhum detalhe,basta conferir as poucas linhas de código requeridas por ele:

Método ParseSQL – utilizado para gerar o parse do script da tabela, onde são verificadas assintaxes e críticas de validação necessárias para a criação dos campos (objetos TField);

1.

Método CreateTempDefinitionTable – utiliza o script gerado no passo anterior para gerar atabela contendo os campos especificados neste script agora já validado.

2.

Note que este aplicativo acima utiliza várias funções de teste, geradas randomicamente para fazer acarga em um objeto do tipo TClientDataSet e assim gerando finalmente a tabela em si criada. Esteprograma utiliza alguns critérios diferenciados para otimizar nossos testes bem como algumas outras“perfumarias” para facilitar a compreensão e a intuição com o usuário. Vamos elencar algumas:

O tipo TFieldType foi declarado novamente no nosso programa, para sobrepor este tipotradicional já criado na unit DB.pas. O objetivo é reduzir os itens deste conjunto pelo fato de nãohaver necessidade de trazer todos para uma questão de velocidade e praticidade. Posteriormentetambém será criado um componente descendente de TDataSet que implementará este tiporedeclarado pois não haverá suporte a todos os tipos existentes, como ftUnknown, ftADT, ftArray,ftReference, etc;

1.

Foi criado um tipo TBoolean apenas para facilitar a geração de valores booleanos;2. Foi criada uma diretiva condicional de compilação para acionar os testes ({$DEFINE TEST};3. Foram criadas 4 funções que geram valores randômicos um para cada tipo delas:4.

GenerateRandomStrings – Retorna uma string randômica;1. GenerateRandomFieldType – Retorna um objeto do tipo TFieldType randômico;2. GenerateRandomSize – Retorna um integer randômico;3. GenerateBooleanValues – Retorna um boolean randômico.4.

Foram implementadas várias funções interessantes para um objeto de TDBGrid:5. Evento OnDrawColumnCell – exibir objetos de TCombobox para certos campos

dentro de um TDBGrid, onde se seleciona e o valor é guardado de volta neste TDBGrid;1.

Evento OnColExit – colocar os objetos TCombobox para invisível, disponibilizados deacordo com o campo especificado;

2.

Evento OnKeyDown – tratamentos especiais na manipulação do evento “Ctrl +3.

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

15 de 16 23/12/2015 16:37

Page 16: Artigos - The Club · Password Teste123 (senha ficticia) DataBase Apenas o nome da Base de Dados Tabela 02. Dentro da mesma pasta criada anteriormente iremos implementar nosso exemplo

Delete”, onde a mensagem padrão (prompt) do Delphi é abortada e a função de recalcular osvalores do atributo “Position” é chamada.

Evento OnKeyUp e OnCellClick: ambas tem a mesma finalidade – que significa quandouma célula do objeto TDBGrid é selecionada ela terá o mesmo efeito de “clicada” – exibindoseus dados em um objeto de TStatusBar abaixo. Isso é muito importante para simular o efeito de“refresh” em uma célula, trazendo seus novos dados nesta célula ou servindo de filtro para umoutro objeto de TDBGrid (mestre/detalhe), onde basta clicar em uma linha que automaticamentea segunda lista exibirá os resultados – muito importante onde o usuário navega esse objeto deTDBGrid por setas, acionando o evento de clique da célula de modo prático.

4.

Funciona dessa maneira:

O usuário define quantos campos serão criados através de um objeto de TEdit correspondente;1. O usuário escolhe o nome das colunas, tipo, tamanho e obrigatoriedade de cada uma delas;2. O usuário clica no botão “Recreate Tests”;3. O aplicativo gera o script com os dados dos campos criados bem como a lista de meta-dados

utilizados pelo componente;4.

O usuário poderá editar este script, alterando dados dos atributos, podendo também incluir ouremover outros;

5.

O usuário clica no botão “Parser Script (from THVParser component)”;6. O aplicativo valida o script gerado no passo anterior;7. O usuário clica no botão “Create Table (from THVParser component)”8. O aplicativo gera finalmente o banco com as colunas criadas com sucesso, de acordo com o

especificado.9.

ConclusãoNeste artigo vimos algumas ilustrações de técnicas de criação de atributos para uma tabela

qualquer via classe TClientDataSet – tradicional e comum – mas automatizado via componente THVParseronde o desenvolvedor apenas descreve um layout customizado e parametrizado contendo informaçõesdestes campos para serem interpretados e processados gerando a saída deles (coluna criada) pelachamada da função AddFieldDef (TFieldDefs – DB.pas).

Interessante é que o componente encapsula todas as funcionalidades necessárias para a criaçãodos atributos desejados e apenas devolve um objeto de TClientDataSet já instanciado e criado – umaplicativo pronto para a criação de tabelas.

Um utilitário criador de tabelas em Delphi vai exigir basicamente que os atributos estejamcorretamente definidos e preenchidos – então as validações são executadas e no caso de sucesso oprograma cria a tabela – neste nosso caso está em memória mas como é TClientDataSet facilmentepodemos persistir ela (ex: método saveToFile) – e em um outro aplicativo demo vindouro (na próxima ediçãoiremos ilustrar a persistência automática com estes atributos via objeto TStream) vamos compreenderformas interessantes na manipulação de objetos persistentes utilizando classes descendentes de TDataSet– nosso novo componente THVDataSet que irá também implementar suporte a um descendente de TStream!Portanto vamos “brincar” de coleções e persistência na próxima edição, juntamente com mais um utilitáriodeste componente abordado THVParser! Bons estudos e até lá!

Sobre o Autor

Hamden Vogel

Consultor Técnico The Club

E-mail: [email protected]

Artigos http://theclub.com.br/restrito/revistas/201511/1511.aspx

16 de 16 23/12/2015 16:37