SlideShare uma empresa Scribd logo
janeiro
2015
janeiro
2015
janeiro
2015
03
20
Índice
Dicas The Club
30
Editorial
04
10
Autor: Hamden Vogel
05
Autor: Marlon Aparecido Branco Valentino
26
Delphi - Gerador de Tabelas
e Consultas através de um
parser SQL - parte II
Autor: Thiago C. Montebugnoli
Autor: Luciano Pimenta
Bootstrap – Uma ideia geral
sobre este Framework
Android Studio - Volley
SQL Server – Explorando
recursos para Importação e
Exportação de Dados
janeiro
2015
04
Delphi é marca registrada da Borland International,
as demais marcas citadas são registradas
pelos seus respectivos proprietários.
Thiago Montebugnoli- Editor Chefe
thiago@theclub.com.br
Caro amigo,
Primeiramentegostariadedesejarumótimoiníciodeanoequenossaparceria
continue a mesma por toda esta nova caminhada.
Nestaedição,nossocolunistamensalLucianoPimenta,continuaabordandoo
usodoAndroidStudio.Elenosensinaautilizarumabibliotecaparatrabalharcom
oprotocoloHTTP,denominadaVoley.AmesmafazrequisiçõesWEBparatrabalhar
comdadosJSONouimagens,sendoumadasmaisindicadaspelasuapraticidade
evelocidade.JáNossoConsultorMarlonAparecidoBrancoValentinoéoautordo
artigo“Bootstrap–umaideiageralsobreesteframework”.Comooprópriotítulo
indica,elenos orienta e apresenta alguns dos principais recursos desta poderosa
ferramenta “front-end”, agilizando e aplicando diversas funcionalidades com
um volume de trabalho muito baixo. Eu transformei uma dica em um pequeno
artigo que explora um dos recursos do SQL Server, a importação e exportação de
Dados utilizando o “SQL Server Integration Services”, uma ferramenta altamente
recomendada para executar operações de Extração, Transformação e Carga de
Dados envolvendo inúmeras plataformas. Já nosso colaborador Hamden Vogel,
na segunda parte do artigo sobre o “Gerador de Tabelas e Consultas através de
umParserSQL”discutemaisalgunsmétodossobreestainteressanteferramenta,
procurando sempre desenvolver de uma forma abstrata se tornando mais uma
alternativa de execução de comandos SQLs para o componente ClientDataSet e
seus descendentes.
Não esqueça de dar uma conferida em nossa seção de Dicas e Truques.
Desejo a todos uma boa leitura e até o mês que vem!
Abraços
Av. Profº Celso Ferreira da Silva, 190
Jd. Europa - Avaré - SP - CEP 18.707-150
Informações e Suporte: (14) 3732-1529
Internet
http://www.theclub.com.br
Cadastro: cadastro@theclub.com.br
Suporte: suporte@theclub.com.br
Informações: info@theclub.com.br
Skype Cadastro: theclub_cadastro
Skype Suporte: theclub_linha1
theclub_linha2
theclub_linha3
www.twitter.com/theclubbr
Copyright The Club 2013
Diretor Técnico
Marcos César Silva
Diagramação
Vitor M. Rodrigues
Design
Vitor M. Rodrigues
Revisão
Denise Blair
Colunistas
Hamden Vogel
Jeferson Silva de Lima
Luciano Pimenta
Lucas Vieira de Oliveira
Thiago Cavalheiro Montebugnoli
Impressão e acabamento:
GRIL - Gráfica e Editora
Taquarituba-SP - Tel. (14) 3762-1345
Reprodução
A utilização, reprodução, apropriação, armazenamento em banco
de dados, sob qualquer forma ou meio, de textos, fotos e outras
criações intelectuais em cada publicação da revista “The Club
Megazine” são terminantemente proibidos sem autorização
escrita dos titulares dos direitos autorais.
Editorial
janeiro
2015
05
Introdução
Naépoca emque estamos à áreade desenvolvimento de aplicativos para
web e mobile está trabalhando para entregar os melhores produtos, com isso
os prazos que estão cada vez mais curtos, logo precisamos de um framework
front-end que, ao mesmo tempo, agilize e facilite o desenvolvimento, e basta
pesquisar um pouco que encontrará dezenas deles. O Bootstrap está entre
os melhores, criado pelos desenvolvedores do Twitter, é massivamente utili-
zado por desenvolvedores e agências ao redor do mundo, pois responde aos
requisitos que um desenvolvedor front-end necessita para o mercado atual
de softwares para web.
ParaquemnãoentendeinglêsaGlobo(http://globocom.github.io/boots-
trap/) traduziu a documentação (pois o eles utilizam em projetos internos da
empresa),porémaversãoqueelesutilizamestádefasada,emvistaqueaversão
atualdoFrameworkBootstrapestánav3.3.1eaversãotraduzidaestánav2.2.2.
Quem já é familiarizado com o inglês basta entrar no site oficial do Bootstrap
(http://www.getbootstrap.com)quesempreencontraráoFrameworkemsua
versão mais atualizada, que apresenta os seguintes recursos:
• Designresponsivo,seugridsystemtemcomofoco“mobilefirst”,o
layout se adapta ao tamanho da tela do dispositivo móvel, seja ele um celular
de 4 polegadas ou um tablete com 8 polegadas (o design responsivo pode ser
desativado se necessário);
• Conta com um sistema de Grids bem fluido e manipulado simples;
• A biblioteca de estilos possui um design moderno para manipular
os elementos básicos do HTML, como: buttons, tables, forms, etc;
• Ainda possui alguns elementos HTML extras, como: Drop-down,
menus de navegação, tanto vertical quanto horizontal, paginação, navegação
estrutural, etc;
• O JavaScript que acompanha o projeto vem na forma de JQuery
plugins, onde o usuário tem alguns elementos adicionais, como: caixas de
diálogo, dica de ferramenta, estados de botões, carrossel, etc.
OsitedoBootstrapsempreestácomaversãomaisatualizada,paraquem
Bootstrap – Uma ideia
geral sobre este Framework
busca obter a ultima versão basta entrar no site, logo na primeira página já
tem um link de download, abaixo do botão de download ele informa a versão
atual do framework, como é exibido na imagem 01:
Imagem 01. Site.
Conhecendo o Framework
No site oficial do Bootstrap é possível encontrar vários exemplos que po-
demserutilizadoscomaBibliotecafornecidaemseusarquivosCSSeJavaScript.
Para quem quer começar a trabalhar com o Framework Bootstrap, a primeira
regra para utilizá-lo em seu projeto, é a que ele necessitará de migração para
a versão do HTML5(caso não esteja na versão atual da linguagem), porque
ele faz o uso de alguns elementos HTML e propriedades CSS que requer o uso
do doctype HTML5.
Introduzindo alguns elementos do Bootstrap
Começando pelo CSS, que pode ser acessado pela parte superior do site
naaba‘CSS’,quandoselecionadodirecionaousuárioàpáginaondepodemser
encontradosdiversosexemplosdeelementosHTMLaprimoradoseestilizados
pelo CSS do framework.
Como foi citado anteriormente, o Bootstrap é “mobile first”, que significa
Dispositivo móvel em primeiro lugar, o que da preferência ao design respon-
sivo. Para assegurar uma representação apropriada da página no dispositivo
móvel e o “Zoom” ao toque do usuário, basta adicionar a viewport meta tag
janeiro
2015
06
dentro do <head>:
<meta name=”viewport”
content=”width=device-width,
initial-scale=1”>
Paradesativaresserecursobastaadicionar“user-scalable=no”naviewport
meta tag, use-o com cuidado porque isso pode não agradar muito o usuário,
vai ficar igual a linha de código abaixo:
<meta name=”viewport”
content=”width=device-width,
initial-scale=1, maximum-
scale=1, user-scalable=no”>
Na página do CSS há alguns exemplos de botões utilizando o Bootstrap,
para acessar essa parte da página é necessário procurar ao lado direito da
páginanomenutemumaopçãochamada“Buttons”eeleexibiráváriasopções
de botões, como os da imagem 02 logo abaixo:
Imagem 02. Exemplo de Botões.
Código do exemplo exibido na imagem 02 está na ordem da esquerda
para a direita da imagem:
<!-- Botão padrão -->
<button type=”button” class=”btn
btn-default”>Default</button>
<!-- Da peso extra no visual e
identifica a primeira acao em um
conjunto de botoes -->
<button type=”button” class=”btn
btn-primary”>Primary</button>
<!-- Identifica o sucesso de uma
acao ou um comando positivo -->
<button type=”button” class=”btn
btn-success”>Success</button>
<!-- Botao para o contexto da
informação de uma mensagem de
alerta -->
<button type=”button” class=”btn
btn-info”>Info</button>
<!-- Indica que deve tomar
cuidado com a seguinte acao
action -->
<button type=”button” class=”btn
btn-warning”>Warning</button>
<!-- Indica perigo ou uma acao
negativa -->
<button type=”button”
class=”btn btn-danger”>Danger</
button>
<!-- Tira a enfase de um botão,
fazendo-o parecer como um link
-->
<button type=”button” class=”btn
btn-link”>Link</button>
Componentes do Bootstrap
OBootstraptemdúziasdecomponentesreutilizáveisfeitosparaproviden-
ciariconografia,dropdowns,navegação,paginação,alertas,emuitomais.Para
ter acesso aos componentes do Bootstrap basta acessar a aba Components
do site oficial e será direcionado à página.
A Iconografia do Bootstrap é bem simples de utilizar, basta escolher o
ícone desejado e copiar o nome da classe referente ao ícone, como mostra a
imagem 03 logo abaixo:
Imagem 03. Tipos de Icones.
Depois utilizá-la na classe do elemento HTML. Na prática o código fonte
fica desta maneira:
class=”glyphicon glyphicon-
star”
Exemplo de um Dropdown button mostrado mostrado na imagem 04,
quetambémfazpartedoscomponentesreutilizáveisdisponíveisnabiblioteca
do framework:
janeiro
2015
07
Imagem 04. Exemplo de DropDown.
Código do exemplo mostrado na imagem 04 utilizando Bootstrap:
<div class=”dropdown”>
<button class=”btn btn-default
dropdown-toggle” type=”button”
id=”dropdownMenu1” data-
toggle=”dropdown” aria-
expanded=”true”>
Dropdown
<span class=”caret”></span>
</button>
<ul class=”dropdown-
menu” role=”menu” aria-
labelledby=”dropdownMenu1”>
<li role=”presentation”><a
role=”menuitem” tabindex=”-1”
href=”#”>Action</a></li>
<li role=”presentation”><a
role=”menuitem” tabindex=”-1”
href=”#”>Another action</a></
li>
<li role=”presentation”><a
role=”menuitem” tabindex=”-1”
href=”#”>Something else here</
a></li>
<li role=”presentation”><a
role=”menuitem” tabindex=”-1”
href=”#”>Separated link</a></
li>
</ul>
</div>
JavaScript
UmdosrecursosmaisinteressantesdoframeworkésemdúvidasoJavaS-
cript,localizadonaabasuperiordositeescrito“JavaScript”,poiseletrazàvida
vários componentes do Bootstrap vários plug-ins JQuery customizados. Eles
podemserfacilmenteincluídosemseuprojeto,umporum(utilizandooarquivo
“*.js” individual do Bootstrap) ou todos de uma vez (Usando o “bootstrap.js”
ou o minimizado “bootstrap.min.js”).
Começando pelas janelas modais disponibilizadas pelo framework elas
são simplificadas, porém flexíveis, com diálogos prontos que requerem o
mínimo de funcionalidade e padrões inteligentes. Na imagem 05 será exibido
um exemplo de janela modal estático:
Imagem 05. Exemplo de Janelas.
Para chamar a janela modal em um botão, por exemplo, é necessário
utilizar um identificador dentro da primeira tag <div> que chama a classe
“.modal fade”, e o código do botão fica da seguinte maneira:
<button class=”btn btn-
default” type=”button”
data-toggle=”modal” data-
target=”#meuModal”>
Observe no código abaixo que a primeira tag <div> está com um identi-
ficador “meuModal” para o elemento, que é chamado no código do botão a
cima, referindo-se à janela modal exibida na imagem 05:
<div class=”modal fade”
id=”meuModal” tabindex=”-1”
role=”dialog” aria-
labelledby=”myModalLabel” aria-
hidden=”true”>
<div class=”modal-dialog”>
<div class=”modal-content”>
<div class=”modal-
header”>
<button type=”button”
class=”close” data-
dismiss=”modal”><span aria-
hidden=”true”>&times;</
span><span class=”sr-
only”>Close</span></button>
<h4 class=”modal-
title”>Modal title</h4>
</div>
<div class=”modal-body”>
<p>One fine
body&hellip;</p>
</div>
<div class=”modal-
footer”>
<button type=”button”
class=”btn btn-default” data-
dismiss=”modal”>Close</button>
janeiro
2015
08
<button type=”button”
class=”btn btn-primary”>Save
changes</button>
</div>
</div><!-- /.modal-content
-->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
Outro recurso que é cobiçado pelos usuários do Bootstrap é sem dúvi-
das o Carousel(Carrossel em tradução livre), nada mais é do que um “slide”
de imagens que circula pelos elementos como um carrossel, se localiza ao
lado direito da página JavaScript com o nome Carousel, clicando na opção
ele o direcionará para a parte da página que exibe o conteúdo referente ao
recurso.O“carrossel”doBootstrapnãoésuportadopelasversõesdo8e9do
Internet Explorer, pois o framework utiliza o CSS3 que não é suportado pelas
respectivas versões do navegador. Para quem ficou curioso para saber como
é funciona o “Carousel” do Bootstrap, logo abaixo na imagem 06 segue um
exemplo do recurso:
Imagem 06. Exemplo de Carrossel.
Este é o código do exemplo mostrado na imagem 06:
<div id=”carousel-example-
generic” class=”carousel slide”
data-ride=”carousel”>
<!-- Indicators -->
<ol class=”carousel-
indicators”>
<li data-target=”#carousel-
example-generic” data-slide-
to=”0” class=”active”></li>
<li data-target=”#carousel-
example-generic” data-slide-
to=”1”></li>
<li data-target=”#carousel-
example-generic” data-slide-
to=”2”></li>
</ol>
<!-- Wrapper for slides -->
<div class=”carousel-inner”
role=”listbox”>
<div class=”item active”>
<img src=”...” alt=”...”>
<div class=”carousel-
caption”>
...
</div>
</div>
<div class=”item”>
<img src=”...” alt=”...”>
<div class=”carousel-
caption”>
...
</div>
</div>
...
</div>
<!-- Controls -->
<a class=”left carousel-
control” href=”#carousel-
example-generic” role=”button”
data-slide=”prev”>
<span class=”glyphicon
glyphicon-chevron-left” aria-
hidden=”true”></span>
<span class=”sr-
only”>Previous</span>
</a>
<a class=”right carousel-
control” href=”#carousel-
example-generic” role=”button”
data-slide=”next”>
<span class=”glyphicon
glyphicon-chevron-right” aria-
hidden=”true”></span>
<span class=”sr-only”>Next</
span>
</a>
</div>
Paraadicionarlegendaàsimagensdoslide,énecessáriocolocardentrode
qualquer classe chamada “item” (identifica cada item que compõem o slide)
um elemento HTML que ele será alinhado e formatado automaticamente no
slide, como é exibido na imagem 07:
Imagem 07. Exemplo de Legendas.
janeiro
2015
09
O exemplo da imagem 07 foi customizado por mim, é apenas um exem-
plar de como ficaria o “carousel“ com uma imagem e legendas, o código da
imagem 07 mostra as tags HTML <img> que declara o caminho da imagem,
o <h3> responsável pelo titulo da imagem e o <p> pelo subtítulo da imagem,
observe o código abaixo:
<div class=”item”>
<img src=”~/Content/image2/
helix_nebula.jpg” alt=”...” >
<div class=”carousel-
caption”>
<h3>Nebulosa de Hélix</h3>
<p>O Olho de Deus</
p>
</div>
</div>
Conclusão
ComessaintroduçãoaoFrameworkBootstrapépossívelcomeçarautilizar
aferramentadeformabásica,incluindoalgunsdeseusrecursosaseuAplicativo
paraweb,comoosexemplosqueforamcitadosnesteartigo.Eparaquemnão
suporte@theclub.com.br
Marlon Aparecido Branco Valentino
Consultor Técnico The Club.
Sobre o autor
tem conhecimento em desenvolvimento para web e se interessou pela área,
recomendo profundamente que comece a estudar linguagens como HTML5,
CSS3, JavaScript e JQuery para melhor entender os conceitos do framework
e os exemplos presentes no site, já quem possui um conhecimento básico
ou avançado em HTML, CSS e JavaScript, também recomendo que estude
profundamente o framework Bootstrap, pois além de dar facilitar e agilizar o
desenvolvimento,eledaoutracaraaoseuprojeto,sejaeleumalojavirtualou
um site empresarial, e com certeza fará a cabeça dos usuários.
janeiro
2015
10
O
nome pode parecer estranho, mas o Volley é uma biblio-
teca HTTP para trabalhar com requisições em aplicações
Android. Existem outras maneiras de fazer requisições
(Async Task e org.apache), mas a biblioteca da Google é a
mais indicada, pois é fácil e principalmente, rápida.
Com o Volley, podemos fazer requisições para retornar ou enviar dados
JSONebaixarimagens,essasduas,praticamenteasnecessidadesmaiscomuns
emaplicaçõesAndroidatualmente.Outravantagem,quenãoprecisamoscriar
threads para as requisições (é necessário uma thread separada da principal),
o Volley, internamente, cria essa thread na aplicação.
Mais informações em: http://developer.android.com/training/volley/
index.html
Download e instalação
Precisamos instalar a ferramenta Git para baixar a última versão da bi-
blioteca. No download deste artigo, está disponível a última, caso não deseje
baixar. Baixe a ferramenta em: http://git-scm.com/download/win.
A instalação da ferramenta é bem simples. Acesse o Git Bash, que é um
prompt de comando, e digite o seguinte código:
git clone https://android.
googlesource.com/platform/
frameworks/volley
Veja na Figura 1 a finalização do download do Volley pelo Git.
Android Studio –
Volley
Figura 1. Baixando o Volley, usando Git
O Git vai baixar a biblioteca na pasta do usuário logado no Windows com
o nome volley. Agora, precisamos adicionar a biblioteca no Android Studio.
Nota: o Android Studio saiu da versão beta. Veja em http://deve-
loper.android.com/sdk/index.html a última versão disponível. A Google
salienta que o Android Studio é a IDE oficial para Android, não dando
mais suporte para plugins de outras IDEs.
CrieumnovoprojetonoAndroidStudio.Escolhaqualquertemplate.Após,
acesseaestruturadoprojetousandoomenuFile>ProjectStructure(Figura2).
Crie no botão de + (New Module).
Veja a Figura 2. Estrutura do projeto Android
No wizard escolha Import Existing Project (Figura 3) e clique em Next.
Veja a Figura 3. Importando um projeto existente
janeiro
2015
11
No próximo item, escolha o caminho onde estão os arquivos do Volley
(Figura 4). Escolha a raiz do diretório. Clique em Finish.
Veja a Figura 4. Escolhendo o diretório do Volley
OGradlecomeçaraarecompilaroprojeto.Voltandoateladeestruturado
projeto,cliqueemappenaabaDependencies.Nobotãode+,escolhaModule
dependency. Será mostrado o módulo adicionado anteriormente (Figura 5).
Veja a Figura 5. Configurando o Volley ao nosso projeto
Clique em OK e OK.
Nota: o Volley necessita da API 19. Caso você não tenha instalado
essa API, uma mensagem será mostrada e um link para baixar a API.
Também o Build Tools deve ser atualizado com a versão 21. O Android
Studio avisa e facilita a instalação. Após, na janela Project temos a pasta do Volley com suas classes incor-
poradas ao projeto (Figura 6).
Figura 2. Estrutura do projeto Android
Figura 3. Importando um projeto existente
Figura 4. Escolhendo o diretório do Volley
Figura 5. Configurando o Volley ao nosso projeto
janeiro
2015
12
Listagem 1. Criando um singleton para RequestQueue
Figura 6. Volley adicionado ao projeto
O ícone indica que ele é um módulo.
Criando o primeiro em exemplo
Vamos criar um exemplo simples, para recuperar um JSONObject. Se o
seuaplicativofaráusoconstantedeacessoadadosouimagens,éinteressante
criar uma única instância do objeto RequestQueue, que tem por finalidade
criar as requisições que precisamos.
Com uma única instância, será mais rápido criar/chamar as requisições.
Vamos criar uma classe conforme a Listagem 1.
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.
Request;
import com.android.volley.
RequestQueue;
import com.android.volley.
toolbox.Volley;
public class AppController
extends Application {
public static final String
TAG = AppController.class.
getSimpleName();
private RequestQueue
mRequestQueue;
private static AppController
mInstance;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized
AppController getInstance() {
return mInstance;
}
public RequestQueue
getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.ne
wRequestQueue(getApplicationCon
text());
}
return mRequestQueue;
}
public <T> void
addToRequestQueue(Request<T>
req, String tag) {
req.setTag(TextUtils.
isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void
addToRequestQueue(Request<T>
req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void
cancelPendingRequests(Object
tag) {
if (mRequestQueue != null) {
mRequestQueue.
cancelAll(tag);
}
}
}
A classe, controla a “fila” de requisições para o objeto RequestQueue.
janeiro
2015
13
Listagem 2. Recuperando dados JSON com Volley
No onCreateView (por que criei um projeto com um Fragment), vamos criar o
método para recuperar esses dados, conforme a Listagem 2.
final TextView mTextView
= (TextView)rootView.
findViewById(R.id.textView);
String url =”http://rest-
service.guides.spring.io/
greeting”;
final ProgressDialog
pDialog = new
ProgressDialog(getActivity());
pDialog.
setMessage(“Carregando...”);
pDialog.setCancelable(false);
pDialog.show();
JsonObjectRequest jsonObjReq =
new JsonObjectRequest(Request.
Method.GET,
url, null,
new Response.
Listener<JSONObject>() {
@Override
public void
onResponse(JSONObject response)
{
try {
mTextView.
setText(“Retorno do WS: “ +
response.getString(“content”));
}
catch (JSONException e) {
Toast.
makeText(getActivity(),
e.getMessage(),
Toast.LENGTH_LONG).
show();
}
pDialog.hide();
}
}, new Response.
ErrorListener() {
@Override
public void
onErrorResponse(VolleyError
error) {
Toast.
makeText(getActivity(), error.
getMessage(),
Toast.LENGTH_LONG).
show();
pDialog.hide();
}
});
AppController.getInstance().
addToRequestQueue(jsonObjReq);
O exemplo é simples, a URL http://rest-service.guides.spring.io/greeting
retorna um objeto JSON com dois campos, id e content. A URL foi retirada de
umexemplonainternet.OJsonObjectRequestrecebecomoparâmetrootipo
de requisição (nesse caso um GET), a URL, um JSONObject e um Listener para
o Response e para ErrorResponse.
No Response, é onde manipulamos os dados retornados. No ErrorRes-
ponse, fechamos o ProgressDialog e também, mostramos uma mensagem,
informando o erro. No final, adicionamos a requisição na fila da classe que
criamos anteriormente. Podemos ainda, dar uma “tag” para cada requisição,
ficando fácil se precisarmos cancelar alguma posteriormente.
Temos que “registrar” a classe AppController no AndroidManifest.xml,
pois ela será uma classe da aplicação e não de uma Activity, por exemplo. Ela
ficará instanciada, enquanto a aplicação estiver rodando.
<application
android:name=” lasoftwares.
myapplication.AppController”
android:allowBackup=”true”
...
E por fim, precisamos adicionar a permissão de acesso a internet na
aplicação Android:
<uses-permission
android:name=”android.
permission.INTERNET” />
Rode a aplicação e veja o retorno da requisição (Figura 7).
Figura 7. Retorno da requisição
janeiro
2015
14
Listagem 3. Retornando um array de dados com Volley
sonArrayRequest
O exemplo anterior, é simples, retornamos um JSONObject (assim como
poderia ser uma string, usando StringRequest). Mas na maioria dos casos,
precisamos retornar vários dados, então, para isso, usamos outro objeto, um
JsonArrayRequest.
Adicione um ListView na aplicação. O arquivo JSON é de um exemplo da
internet, vale apenas para fins didáticos, pois tem apenas dois registros. Na
Listagem 3 temos o código para recuperar os dados no ListView.
final ListView lv = (ListView)
rootView.findViewById(R.
id.listView);
String url =”http://api.
androidhive.info/volley/person_
array.json”;
final ProgressDialog
pDialog = new
ProgressDialog(getActivity());
...
JsonArrayRequest jsonObjReq =
new JsonArrayRequest(url,
new Response.
Listener<JSONArray>() {
@Override
public void
onResponse(JSONArray response)
{
ArrayList<String> list =
new ArrayList<String>();
for (int i = 0; i <=
response.length() - 1; i++) {
try {
JSONObject obj =
(JSONObject) response.get(i);
list.add(obj.
getString(“name”));
} catch (JSONException e)
{
Toast.
makeText(getActivity(),
e.getMessage(),
Toast.LENGTH_LONG).
show();
pDialog.hide();
}
}
lv.setAdapter(new ArrayAdapt
er<String>(getActivity(),
android.R.layout.simple_
list_item_1, list));
lv.setFastScrollEnabled(true);
pDialog.hide();
}
}, new Response.
ErrorListener() {
@Override
public void
onErrorResponse(VolleyError
error) {
Toast.
makeText(getActivity(), error.
getMessage(),
Toast.LENGTH_LONG).
show();
pDialog.hide();
}
});
AppController.getInstance().
addToRequestQueue(jsonObjReq);
O exemplo é bastante semelhante ao anterior, com a diferença que o
retorno é um JSONArray e o JsonArrayRequest possui menos parâmetros.
Percorremos o retorno da consulta e adicionamos os valores em uma lista
de string. Após, preenchemos um ListView com essa lista. Veja na Figura 8, o
ListView preenchido.
Figura 8. Preenchendo um ListView com o retorno do JsonArrayRequest
Trabalhando com parâmetros
Muitas vezes, precisamos passar parâmetros para receber o retorno de
um JSONObject ou JSONArray. O Volley possui um bug com parâmetros até a
última versão que testei, que após várias pesquisas, não encontrei o motivo,
mas para contornar o problema, precisamos apenas criar duas classes para
janeiro
2015
15
Listagem 4. Criando as classes JsonObjectRequestCustom e JsonArrayRe-
questCustom
estenderRequestdeJSONObjecteJSONArrayparausarparâmetrosemnossas
requisições.
Nada muito trabalhoso por sinal. Na Listagem 4 temos o código das duas
classes que precisamos criar.
JSONObjectRequestCustom
import com.android.volley.
AuthFailureError;
import com.android.volley.
NetworkResponse;
import com.android.volley.
Request;
import com.android.volley.
Response;
import com.android.volley.
Response.ErrorListener;
import com.android.volley.
Response.Listener;
import com.android.volley.
toolbox.HttpHeaderParser;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncod
ingException;
import java.util.Map;
public class
JsonObjectRequestCustom extends
Request<JSONObject> {
private Listener<JSONObject>
response;
private Map<String, String>
params;
public
JsonObjectRequestCustom(int
method, String url,
Map<String, String> params,
Listener<JSONObject> response,
ErrorListener listener) {
super(method, url,
listener);
this.params = params;
this.response =
response;
// TODO Auto-generated
constructor stub
}
public
JsonObjectRequestCustom(String
url, Map<String, String> params,
Listener<JSONObject> response,
ErrorListener listener) {
super(Method.GET, url,
listener);
this.params = params;
this.response =
response;
// TODO Auto-generated
constructor stub
}
public Map<String,
String> getParams() throws
AuthFailureError{
return params;
}
public Priority
getPriority(){
return(Priority.
NORMAL);
}
@Override
protected
Response<JSONObject> parseNet
workResponse(NetworkResponse
response) {
try {
String js
= new String(response.
data, HttpHeaderParser.
parseCharset(response.
headers));
return(Response.
success(new JSONObject(js),
HttpHeaderParser.
parseCacheHeaders(response)));
}
catch
(UnsupportedEncodingException
e) {
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void
janeiro
2015
16
deliverResponse(JSONObject
response) throws
UnsupportedEncodingException,
JSONException {
this.response.
onResponse(response);
}
}
JSONArrayRequestCustom
import com.android.volley.
AuthFailureError;
import com.android.volley.
NetworkResponse;
import com.android.volley.
Request;
import com.android.volley.
Response;
import com.android.volley.
Response.ErrorListener;
import com.android.volley.
Response.Listener;
import com.android.volley.
toolbox.HttpHeaderParser;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.UnsupportedEncod
ingException;
import java.util.HashMap;
import java.util.Map;
public class
JsonArrayRequestCustom extends
Request<JSONArray> {
private Listener<JSONArray>
response;
private Map<String, String>
params;
public
JsonArrayRequestCustom(int
method, String url,
Map<String, String> params,
Listener<JSONArray> response,
ErrorListener listener) {
super(method, url,
listener);
this.params = params;
this.response =
response;
}
public
JsonArrayRequestCustom(String
url, Map<String, String> params,
Listener<JSONArray> response,
ErrorListener listener) {
super(Method.GET, url,
listener);
this.params = params;
this.response =
response;
}
@Override
public Map<String,
String> getParams() throws
AuthFailureError{
return params;
}
public Priority
getPriority(){
return(Priority.
NORMAL);
}
@Override
protected
Response<JSONArray> parseNet
workResponse(NetworkResponse
response) {
try {
String js
= new String(response.
data, HttpHeaderParser.
parseCharset(response.
headers));
return(Response.
success(new JSONArray(js),
HttpHeaderParser.
parseCacheHeaders(response)));
}
catch
(UnsupportedEncodingException
e) {
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void
deliverResponse(JSONArray
response) throws
janeiro
2015
17
Listagem 5. Usando parâmetros na requisição
Listagem 6. carregando imagens com ImageRequest
UnsupportedEncodingException,
JSONException {
this.response.
onResponse(response);
}
}
A ideia é simples, onde atribuímos para a propriedade params, o valor
passado dos parâmetros. Vamos adaptar o exemplo do ListView para uma
consultacomparâmetros.VejanaListagem5amudançadocódigodoexemplo.
...
Map<String, String> params =
new HashMap<String, String>();
params.put(“nCdAtividade”,
“1”);
JsonArrayRequestCustom
jsonObjReq = new
JsonArrayRequestCustom(
url, params,
new Response.
Listener<JSONArray>() {
@Override
public void
onResponse(JSONArray response)
{
ArrayList<String> list =
new ArrayList<String>();
for (int i = 0; i <=
response.length() - 1; i++) {
try {
JSONObject obj =
(JSONObject) response.get(i);
...
O código é muito semelhante ao anterior, com a diferença que estamos
usando a nossa classe, e possuímos os parâmetros. A URL desse exemplo é
de um projeto meu, portanto, não posso passar a mesma, mas o resultado é
o retorno dos dados, de acordo com o parâmetro solicitado.
Veja na Figura 9, o resultado da consulta (os dados são de testes do meu
aplicativo).
Figura 9. Preenchendo um ListView com o retorno parametrizado da consulta
Imagens com Volley
Para carregar imagens usando Volley mostrarei duas maneiras. Podemos
usar o ImageRequest de um modo bem simples. Veja na Listagem 6 o código
para carregar a imagem em um ImageView (adicione um na aplicação).
String url = “http://www.
michenux.net/wp-content/
gallery/android/android-256.
png”;
final ImageView mImageView
= (ImageView)rootView.
findViewById(R.id.imageView);
ImageRequest request = new
ImageRequest(url,
new Response.
Listener<Bitmap>() {
@Override
public void
onResponse(Bitmap bitmap) {
mImageView.
setImageBitmap(bitmap);
}
}, 0, 0, null,
new Response.ErrorListener()
{
public void
onErrorResponse(VolleyError
error) {
janeiro
2015
18
Listagem 7. Modificando a AppController para usar ImageLoader
Listagem 8. Carregando imagens com o ImageLoader
//imagem de erro ou
mensagem que não pode carregar
}
});
AppController.getInstance().
addToRequestQueue(request);
O ImageRequest necessita do caminho da imagem (URL) e dois Listeners,
muito semelhante ao exemplo do JsonObjectRequest. Na primeira execução,
dependendo do tamanho da imagem escolhida e sua conexão, a imagem
pode demorar a ser exibida. Na segunda execução, a imagem é mostrada
mais rapidamente.
Caso queira mostrar para o usuário o carregamento, use o mesmo exem-
plo do ProgressDialog mostrado neste artigo. Veja na Figura 10 a imagem
carregada na aplicação.
Figura 10. Imagem carregada usando o ImageRequest
Outra maneira de carregar imagens, é usando o ImageLoader. Para isso,
vamos modificar a classe AppController. Veja na Listagem 7 as modificações.
private ImageLoader
mImageLoader;
...
@Override
public void onCreate() {
...
mImageLoader = new
ImageLoader(getRequestQueue(),
new ImageLoader.ImageCache()
{
private final
LruCache<String, Bitmap>
cache = new
LruCache<String, Bitmap>(20);
@Override
public Bitmap
getBitmap(String url) {
return cache.get(url);
}
@Override
public void putBitmap(String
url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
...
public ImageLoader
getImageLoader() {
return mImageLoader;
}
Declaramosumavariávelprivada.NoOnCreate,adicionamosocódigopara
instanciar essa variável e o método que retorna a mesma. Para instanciar o
ImageLoader,usamosaclasseLruCachequearmazenaaimagememcacheno
device. Mais fácil que exemplos onde criamos a classe para o cache.
Para carregar a imagem, usamos o código da Listagem 8.
final ImageView mImageView
= (ImageView)rootView.
findViewById(R.id.imageView);
ImageLoader mImageLoader =
AppController.getInstance().
getImageLoader();
String IMAGE_URL = “http://
fs04.androidpit.info/a/34/82/
android-recyclerview-w-volley-
3482b6-w192.png”;
mImageLoader.get(IMAGE_
URL, ImageLoader.
getImageListener(mImageView,
janeiro
2015
19
R.drawable.ic_default,
R.drawable.ic_error));
Pegamos a instância do ImageLoader do AppControler. O get do Image-
Loader, recebe como parâmetro a URL da imagem e o getImageListener. No
Listener, indicamos o ImageView e duas imagens. A primeira, é para uma
imagem padrão e a segunda é para uma imagem de erro.
Veja o carregamento da imagem na Figura 11.
Figura 11. Carregando imagens com ImageLoader
Na imagem padrão, podemos colocar uma com o texto indicando o car-
regamento, para que o usuário não pense que a aplicação travou. Caso você
tenha pensado em qual maneira usar, para, por exemplo, mostrar imagens
em um ListView, indico que a segunda é a que tem a melhor performance.
Conclusões
Vimos neste artigo, como trabalhar com a biblioteca Volley para fazer re-
quisiçõesWebparatrabalharcomdadosJSONouimagens.Éabibliotecamais
indicada, pois é desenvolvida pela Google e mais rápida que qualquer outra
maneira de fazer requisições em aplicações Android. Migrei meus projetos
para o Volley e não me arrependi.
Um grande abraço a todos e até a próxima!
www.lucianopimenta.net
Luciano Pimenta
LucianoPimenta(NOVODOMINIO:www.lucianopimenta.com)édesenvolvedorDelphi/C#
paraaplicaçõesWebcomASP.NET,WindowscomWin32eWindowsFormscom.NET.Palestrante
da 4ª edição da Borland Conference (BorCon) e da 1ª Delphi Conference.
É MVP Embarcadero, grupo de profissionais que ajudam a divulgar o Delphi no mundo.
Atualmente é desenvolvedor da SoftDesign fábrica de softwares em Porto Alegre-RS.
Autor de mais de 90 artigos e de mais de 600 vídeos aulas publicadas em revistas e sites
especializados, além de treinamentos presenciais e multimídias. É consultor da FP2 Tecnologia
(www.fp2.com.br) onde ministra cursos de programação e banco de dados.
Sobre o autor
janeiro
2015
20
C
aros leitores, essa edição é a continuação do artigo anterior,
discursando sobre o tema de desenvolvimento de um parser
SQL para XML persistindo no formato MyBase, podendo
claramente ser estendido para stream ou outros formatos
possivelmente sem problemas.
VimosofuncionamentodeumCRUD(Create/Read/Update/Delete),bem
comoacriaçãodeumbancoeseufuncionamento,tudoviaSQLcomolinhade
comandoporpartedoaplicativo–nenhumcomandointernodecomunicação
com um clientdataset para carregamento e exibição destes dados.
Dando continuação, vamos explorar mais a fundo nosso analisador sintá-
tico, reprisar alguns conceitos visto que foram reformulados (tanto em telas
como no fonte) e discorrer sobre nosso projeto ilustrando o funcionamento
básico do mesmo.
Figura01–Teladecriaçãodobancodedados,ondeosdadossãoexibidosnagrid
viaclientdatasetderetorno;oslistboxesdecolunasevaloressãopopuladosdecorrentes
Delphi-GeradordeTabelas
eConsultasatravésdeumparser
SQL - parte II
do filtro do nosso parser em ação.
Nesta figura acima vemos que o parser interpretou cada palavra, uma
por uma, retirou alguns caracteres como vírgula e aspas (simples e duplas)
e fez o tratamento adequado para cada uma delas. Nosso programa faz uso
pesadodelistboxesparatratamentoprincipalmentedecampos“chave-valor”
(coluna e valores) onde para cada tipo de instrução terá sua implementação
adequada, conforme requisitos padrões de SQL (as cláusulas tradicionais de
insert, update, etc);
Figura 02 – Outro exemplo de criação de um banco de dados chamado “alunos”
– e sua exemplificação via componentes do Delphi como os listboxes preenchidos via
dataset de retorno do parser.
Método Insert
janeiro
2015
21
Figura 03 – Tela de Insert – onde o clientdataset recebe o SQL contendo o insert a
ser executado e o processa de dentro do aplicativo.
OmétodoInsert,DeleteeUpdatefoiexplicadonoitemanterior, deforma
sucinta, onde vamos abordar de forma mais ampla o seu funcionamento, a
seguir:
1. Existem dois clientdataset´s para o funcionamento do projeto. O
primeiro é o clientdataset parser, responsável por extrair a string contendo
o SQL para dentro dele, tratando caracteres e outras regras de validação,
refinando tratamentos de espaços, espaços dentro de aspas simples, chaves
e valores dentro de parênteses, etc;
2. Feito isso, o outro clientdataset receberá ele e com base nele
populará os dados em si, e finalmente estará pronto para exibi-los, podendo
serem salvos – ou não.
Segue o código-fonte do método de gerar insert, responsável por inserir
os dados de dentro do projeto para o XML MyBase.
procedure TForm1.GerarInsert;
var
palavra: string;
nomeTabelaPassou: Boolean;
parametrosPodemInserir:
Boolean;
i: integer;
coluna: string;
sqlFiltro: string;
//field: TField;
begin
if not sqlClientDataSetExists
then
begin
Application.MessageBox(‘O
Banco não foi criado ainda.
Favor voltar na etapa anterior
select’ + #13#10 +
‘para que seja criado
antes’, ‘Informação’, MB_OK +
MB_ICONINFORMATION);
Exit;
end;
if Assigned(sqlClientDataSetS
electBase) then
sqlClientDataSet :=
sqlClientDataSetSelectBase;
if not tempClientDataSet.
Active then Exit;
if (tempClientDataSet.
RecordCount = 0) then Exit;
ListBox2.Items.Clear;
ListBox3.Items.Clear;
nomeTabelaPassou := False;
sqlClientDataSet.Filtered :=
False;
tempClientDataSet.First;
while not tempClientDataSet.
Eof do
begin
palavra :=
AnsiUpperCase(tempClientDataSet.
FieldByName(‘TEXTO’).AsString);
if (palavra <> ‘INSERT’)
and (palavra <> ‘INTO’)
and (palavra <> ‘VALUES’)
then begin
if parametrosPodemInserir
then
begin
if
parametrosPodemInserir then
ListBox3.Items.
Add(StringReplace(palavra,
chr(39), ‘’, [rfReplaceAll]));
end
else
begin
if nomeTabelaPassou
then
ListBox2.Items.
Add(palavra);
nomeTabelaPassou :=
true;
end;
end;
if (AnsiUpperCase(palavra)
janeiro
2015
22
= ‘VALUES’) then
parametrosPodemInserir := true;
tempClientDataSet.Next;
end;
for i := 0 to ListBox2.Count
- 1 do
begin
if i = 0 then
sqlFiltro := sqlFiltro
+ ListBox2.Items.Strings[i] +
‘=’ + QuotedStr(ListBox3.Items.
Strings[i])
else
sqlFiltro := sqlFiltro
+ ‘ and ‘ + ListBox2.
Items.Strings[i] + ‘=’ +
QuotedStr(ListBox3.Items.
Strings[i]);
end;
sqlClientDataSet.Filter :=
sqlFiltro;
sqlClientDataSet.Filtered :=
True;
if sqlClientDataSet.
RecordCount > 0 then Exit;
sqlClientDataSet.Filtered :=
False;
sqlClientDataSet.Insert;
for i := 0 to ListBox2.Count
- 1 do
begin
coluna := ListBox2.Items.
Strings[i];
if not Assigned
(sqlClientDataSet.FieldDefs.
Find(coluna)) then
begin
Application.
MessageBox(‘Coluna não
encontrada.’, ‘Informação’, MB_
OK + MB_ICONINFORMATION);
Exit;
end;
// field := sqlClientDataSet.
fieldByName(coluna);
// if not Assigned(field)
then continue;
sqlClientDataSet.
fieldByName(coluna).AsString :=
ListBox3.Items.Strings[i];
end;
sqlClientDataSet.Post;
sqlClientDataSet.Close;
sqlClientDataSet.Open;
end;
Persistência
ApersistênciaescolhidaparaonossoprojetoédotipoXMLformatomyba-
se,salvodeumclientdataset.TodachamadaaumcommitgeraráoarquivoXML
com o nome da tabela especificada; se a linha SQL for por exemplo “COMMIT
USUARIO” o arquivo “USUARIO.XML” (sim, sempre com letras maiúsculas)
será gerado no mesmo diretório em que o projeto estiver rodando. Para esta
versão será sempre no mesmo local em que o projeto compile. É claro que
evolutivamente poderá ser gerado um stream como saída, ou outras opções
de formatos de arquivo, etc; isso não é o foco agora, e sim a ilustração de
como funciona o processo.
Figura 04 – Tela que exemplifica o processo de salvar e carregar o arquivo XML,
que representa o nosso banco de dados, para este nosso projeto.
Segue abaixo o código-fonte deste procedimento de gerar a gravação,
mais notadamente “gerar o commit”:
procedure TForm1.
GerarCommit(const sql: string);
begin
if not sqlClientDataSetExists
then Exit;
if not sqlClientDataSet.
Active then Exit;
if sqlClientDataSet.
janeiro
2015
23
RecordCount = 0 then Exit;
if Assigned(sqlClientDataSetS
electBase) then
sqlClientDataSet :=
sqlClientDataSetSelectBase;
sqlClientDataSet.
SaveToFile(biblioteca.
GetNextWord(sql, ‘COMMIT’)+
TableExtension , dfXML);
end;
Segueafunçãomuitoutilizadaparaobterapróximapalavradeumastring:
function GetNextWord(const Str,
Find: string): string;
var
i, k: integer;
auxStr: string;
begin
auxStr := Trim(Str);
i := Pos(Find, Str);
Result := Trim(Copy(str, i +
length(Find), length(str)));
k := Pos(‘ ‘, Result);
if k > 0 then
Result := Trim(Copy(Result,
1, k));
end;
Figura05–TeladegeraçãodecommitapartirdalinhadecomandoSQL.Observe
quenestareleaseonomedatabelatambéméesperado(“exemplo:commitnome_da_
tabela”) – sendo que nas próximas versões apenas a palavra reservada commit será
suficiente, podendo também se utilizada o método anterior.
Select´s e mais select´s
Agoraparticularmenteumadaspartesmaisinteressantesdoprojeto,que
éofiltrodeselect´seseusparâmetros.Oprojetocompreenderáostiposmais
famosos, suportados por todos os bancos, e algumas ainda estão por vir nas
próximas releases do aplicativo.
Vamos destacar os tipos de selects suportados nesta corrente versão:
1. Select * from tabela;
2. Select*fromtabelawherecampo=‘isso’andoutrocampo=‘aquilo’;
3. Select campo, outrocampo, maisumcampo from tabela;
4. Select campo, outrocampo, maisumcampo from tabela where
umcamponaocitadoantes = ‘isso’ and maisumoutrocamponaocitadoantes =
‘aquilo’;
5. Select campo as ALIAS1, outrocampo as ALIAS2, maisumcampo as
ALIAS3 from tabela;
6. Select campo as ALIAS1, outrocampo as ALIAS2, maisumcampo as
ALIAS3 from tabela where umcamponaocitadoantes = ‘isso’ and maisumou-
trocamponaocitadoantes = ‘aquilo’;
Por enquanto são estes comandos suportados. Está sendo desenvolvido
paranovasreleasesoutroscomandospadrõesquerestam,comoporexemplo
“Count”, “Top”, “Like”, dentre outros.
Vale lembrar que seleções com Joins (left join, right join, inner join, etc)
tambémnãoestãoimplementadasnestaversão.Seráimplementadaaindaem
versões futuras. No momento são válidas seleções com uma tabela apenas.
Figura 06– Tela de select com alias.
janeiro
2015
24
Figura 07 – Tela de Select com *.
Figura 08 – Tela de select que retorna apenas alguns campos.
Figura 09 – Tela de update.
Figura 10 – Tela de create table.
A tela de criação de tabela (citada acima) permitirá que uma tabela seja
criada como nos tipos padrões de banco de dados relacionais (SGBD) – cria-
das automaticamente via clientdataset, onde campos not null serão required
= false; auto-incremento do tipo AutoInc, chave primária do tipo KeyField =
campoChave, e os tipos serão tratados como DataType; segue exemplo do
código-fonte abaixo:
fDataSet :=
TClientDataSet(myDataSet);
fDataSet.First;
if not myClientDataSet.Active
then
myClientDataSet.
CreateDataSet
else
myClientDataSet.
EmptyDataSet;
myClientDataSet.
DisableControls;
try
while not fDataSet.Eof do
begin
myClientDataSet.Insert;
for i := 0 to fDataSet.
FieldCount - 1 do
begin
Field :=
myClientDataSet.
FindField(fDataSet.FieldList[i].
FieldName);
if Assigned(Field) then
janeiro
2015
25
begin
K := Field.DataSet.
Fields.IndexOf(Field);
myClientDataSet.
FieldDefs.Items[k].DataType :=
fDataSet.FieldDefs.Items[i].
DataType;
case myClientDataSet.
FieldDefs.Items[k].DataType of
ftString:
myClientDataSet.Fields[k].
AsString := fDataSet.Fields[i].
AsString;
ftDate:
myClientDataSet.Fields[k].
AsString := Self.
DefaultDateFormat2(fDataSet.
Fields[i].AsString);
ftFloat:
myClientDataSet.Fields[k].
AsFloat := Biblioteca.
ArredondaComDecimais( fDataSet.
Fields[i].AsFloat, 2);
ftInteger:
myClientDataSet.Fields[k].
AsInteger := fDataSet.
Fields[i].AsInteger;
else //processa tipos
default
myClientDataSet.
Fields[k] := FDataSet.
Fields[i];
end;
Conclusão
Existem várias formas de se comunicar com sistemas gerenciadores de
banco de dados hoje em dia; o que trouxe aqui é um analisador sintático para
realizar de forma abstrata mais uma alternativa de execução de sql´s para
clientdataset´seseusdescendentes,podendodeformaeficienteseremsalvos
e carregados em diferentes customizáveis soluções, no momento a escolhida
foi a forma mais natural – a persistência em xml´s, podendo ser estendido
para arquivos streams, arquivos binários, ou outros tipos de formatos de
arquivos (como por exemplo descendente de TCollection) para a persistência
e extração dos dados. Cada tabela será um arquivo, e cada arquivo residirá
em um diretório conhecido pela aplicação. No caso todos são locais. Poderá
no futuro ser implementado formas de extração de acesso remoto, commits
em lock, dentre outros métodos.
O projeto estará em constante evolução a cada release e será disponibi-
lizado sempre em downloads freewares.
Trazer novos tipos de parser SQL para o desenvolvimento Delphi atual-
mente é trazer novas ideias de implementação de banco de dados, seja para
novos projetos, projetos multi-plataformas, projetos que não necessitem de
implementações/instalações “árduas” com inúmeras configurações/mapea-
mentoscomdll´s,setup´s,programasexternoscomIDE´sdegeraçãodeSQL´s,
etc;trazendoabaixocustomassemperderasegurançaedesempenho–criar
soluções confiáveis de manipulação de dados e principalmente exportáveis
para outros tipos de formato – que tal o output para um TMemoryStream
ou uma customização para um arquivo binário (ou descendente de TStream)
onde somente o aplicativo leia seu conteúdo, ou exportação para arquivos
baseados em uma implementação de “Memory Mapping Files” (usando
CreateFileMappingW) ?
É trazer a luz acessos a banco de dados jamais pensados antes, e na troca
de informações e de implementações, podendo também ser construído em
umWebServicecomJSON,porexemplo,enfim,sãoinúmerasaspossibilidades
em que um desenvolvedor tem em suas mãos – o poder da criação.
suporte@theclub.com.br
Hamden Vogel
Analista de Sistemas pós-graduado em Engenharia de Software pela
UPIS e Programador Delphi com larga experiência desde 2000, tem de-
senvolvido e vendido softwares em Delphi para a África e Estados Unidos,
além do mercado nacional. Colaborou com dicas e componentes para sites
especializadosemDelphi. Tambémdesenvolveemoutraslinguagenscomo
C/C++, ASP, PHP e .NET.
Sobre o autor
janeiro
2015
26
N
este artigo gostaria de abordar um tema muito solicitado
em nosso suporte técnico e em geral pela maioria das pes-
soas, a exportação e importação de dados. A pergunta que
não cala é: Qual a melhor forma para realizar esta tarefa?
Na realidade existem diversas maneiras para realizar esta
tarefa e ultimamente em meus projetos a que se tornou mais prática e ágil foi
a utilização do “SQL Server Integration Services (SSIS)”, uma ferramenta que
usamosparaexecutaroperaçõesde“ETL”,ouseja,(E)xtração,(T)ransformação
e (C)arga de dados, um dos recursos disponíveis na instalação do Banco de
Dados da Microsoft, o SQL Server. Podemos desfrutar deste recurso a partir
da versão 2005, mas ressalto que a base deste artigo será redigido na versão
do SQL Server Express 2008. Caro leitor, caso não possua o mesmo instalado
recomendo a leitura do artigo “Instalando e configurando o SQL Server 2008
Express Edition With Tools” do mês de Março de 2011, que poderá ser encon-
trado no nosso site no link abaixo:
http://www.theclub.com.br/Restrito/Revistas/201103/inst0311.aspx
Características
Podemos destacar algumas características, tais como:
- Recuperação de dados a partir de diversos tipos de fontes;
- Carregar dados em quase qualquer fonte;
- Realização de transformações nos dados, como por exemplo de um tipo
para o outro.
Utilizaremos o assistente de Importação e Exportação de Dados, o que
nos ajudará muito. Teremos como base de exemplo a Importação de dados
oriundos de uma planilha do Excel (.xls) para uma tabela do banco de dados
SQL Server 2008.
Descrição das Estruturas
A seguir estarei comentando sobre a estrutura desta planilha e da tabela.
SQL Server– Explorando
recursos para Importação e
Exportação de Dados
- Planilha do Excel (.xls)
Criaremos alguns campos de diversos tipos, Ver sugestão na Imagem 01.
Figura 01: Planilha Clientes.xls.
- Tabela Clientes
Já a tabela de clientes deverá ser idêntica aos tipos de campos da plani-
lha abordada acima. Podemos conferir o código para criação da mesma na
listagem abaixo.
CREATE TABLE [dbo].[Clientes](
[Id_Cliente] [int] NOT NULL,
[Nome] [varchar](50) NULL,
[Tipo] [varchar](30) NULL,
[Ativo] [int] NULL,
[Data_Nasc] [date] NULL,
CONSTRAINT [PK_Clientes]
PRIMARY KEY CLUSTERED
(
[Id_Cliente] ASC
)WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_
ROW_LOCKS = ON, ALLOW_PAGE_
LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
janeiro
2015
27
Criando o Exemplo
Para iniciarmos iremos executar o “Importar e Exportar Dados (32 bits)”
clicando no menu “Iniciar/Todos os Programas/Microsoft SQL Server 2008”.
Ver imagem 02 abaixo:
Figura 02: Importar e Exportar Dados.
Na tela seguinte nos deparamos com o Assistente de Importação de
Exportação de Dados, o qual irá nos auxiliar a criar pacotes para a tarefa em
questão. Clique em “Avançar”. Ver Imagem 03.
Figura 03: Assistente para Importação e Exportação SQL Server.
NapróximatelaescolheremosaFontedeDados,aorigemdaqualosdados
devemsercopiados,especificaçãoondeosdadosdeverãosercopiados.Neste
caso selecione “Microsoft Excel”, e em “Caminho do Arquivo do Excel”, digite
(ou clique no botão ”Procurar”) o caminho da sua planilha a ser exportada, o
exemploquecrieiparaesteartigoestácomonomede“Clientes.xlsx”.Devemos
também nos atentar para a versão do Excel e checar o item “A primeira linha
possui nomes de colunas”. Ver Imagem 04.
Figura 04:Origem dos Dados.
Após isso aparecerá uma janela para selecionar o Destino, especificação
onde os dados deverão ser copiados, que seria o próprio Banco de Dados SQL
Server, definindo como: “SQL Server Native Client 10.0”. Na caixa de Diálogo
“nome do Servidor” indica onde o mesmo está instalado, como por exemplo:
“THIAGO-NOTESQLEXPRESS”.Emautenticaçãouseamesmadainstalaçãodo
BD.JáemBancodeDadoslocalizaremosaBasedeDadoscriada.Paraproceder
clique no botão “Avançar“, Ver Figura 05.
Figura 05: Destino dos Dados.
Na próxima tela, dentre as duas opções disponíveis, deveremos escolher
a “copiar dados de uma ou mais tabelas ou exibições”. Ver Imagem 06.
Figura 06: Especificar Cópia ou Consulta de tabela.
janeiro
2015
28
Já na próxima etapa irão aparecer as opções para criação ou utilização de
tabelas com base nas planilhas, Ver Figura 07.
Figura 07: Tabelas e Exibições.
Dandoumduplocliquenaopçãodaplanilhaouselecionandoumaclicando
no botão “Editar Mapeamentos…”, aparecerá a seguinte janela, onde você irá
definir os tipos de dados de cada campo, bem como suas propriedades (se
permite valores nulos, tamanho, etc). Nesta mesma janela ao clicar no botão
“Editar SQL…”, teremos a possibilidade para editar a instrução para criação
da tabela na base de dados. Após isso, clique em OK até retornar à janela que
está o botão “Editar Mapeamentos…”. No botão “Visualização”, poderemos
consultar os registros da planilha a serem inseridos no SQL Server. Clique em
“Avançar” para continuar.
Ver Imagem 08.
Figura 08: Mapeamentos de Colunas.
Nas próximas etapas o assistente nos permite revisar todo Mapeamento
de Tipo de Dados, selecionando a tabela para verificar como seus tipos de
dados são mapeados para aqueles no destino. Além disso, podemos escolher
o modo como o assistente lida com problemas de conversão. Ver figura 09.
Veja a Figura 09:Revisão de Mapeamentos de Tipos de Dados.
Após a conclusão teremos um resultado idêntico ao da Figura 10.
Figura 10: Execução Concluída.
Ao abrir a tabela importada no SSMSS (SQL SERVER MANAGEMENT STU-
DIO EXPRESS) e visualizá-lo, tereemos todos os registros da tabela mostrados
janeiro
2015
29
abaixo: Ver Imagem 11.
Figura 11: Resultado da Consulta SQL Server.
Conclusões
Vimos neste artigo o uso prático de um dos recursos presentes no SQL
Server, o “SQL Server Integration Services (SSIS)”. Aprendemos com base na
importação de uma planilha do Excel para uma tabela do SQL Server, mas
ressalto que temos diversas possibilidades como: .Net Frameworks Data
Providers (Dbexpress, ODBC, Oracle, SQL Server, etc...), Microsoft Access,
Microsoft OLE DB (Analysis Services, Data Mining, OLAP, Oracle, etc..). Uma
informação importante que não podia deixar de salientar é que a primeira
Figura 09:Revisão de Mapeamentos de Tipos de Dados.
versãodoSSISfoilançadacomoSQLServer2005.SSISéumasubstituiçãopara
oDataTransformationServices(DTS),queestavadisponívelcomoSQLServer
7.0 e SQL Server 2000. SSIS baseia-se nas capacidades introduzidas com DTS.
Fica aí a dica, um abraço a todos e até o mês que vem!
thiago@theclub.com.br
Thiago Cavalheiro Montebugnoli
adora aprender novas tecnologias. Formado pela Faculdade de Tecnologia de Botucatu
– SP (FATEC), já desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco
de Dados SQL Server e Firebird. Atualmente trabalha no Centro de Processamento de Dados da
Prefeitura Municipal de Itaí-SP é colunista mensal da Revista The Club Megazine e é consultor
Técnico do The Club. Possui as seguintes certificações: MCP - Microsoft Certified Professional,
MCTS-MicrosoftCertifiedTechnologySpecialist,MCAD-MicrosoftCertifiedApplicationDeveloper
e MCSD - Microsoft Certified Solution Developer.
Sobre o autor
janeiro
2015
dicas the club
30
Listagem 1 – Exibir Relatório.
Listagem 2 – Evento OnBeforePrint.
FastReport
Nesta dica vamos utilizar o evento ‘OnBeforePrint’ do ‘frxReport’ para
personalizarmos nosso relatório.
Inicialmente veremos a codificação para chamar o relatório em tela:
frxReport.ReportOptions.Name :=
‘ The-Club ‘;
frxReport.PrintOptions.Printer
:= ‘ Nome da Impressora ‘;
frxReport.PrepareReport;
frxReport.ShowReport;
Imagem 1 – Relatório.
Temos 3 ‘TfrxMemoView’ adicionados a uma banda ‘Title’ vamos alterar
de acordo com codificação abaixo:
procedure
frxReportBeforePrint(Sender:
TfrxReportComponent);
Var
Campos: Array[0..2] of
TfrxMemoView;
begin
Campos[0]:=
TfrxMemoView(frxReport.
FindObject(‘MTheClub’));
Campos[1]:=
TfrxMemoView(frxReport.
FindObject(‘MVisibleT’));
Campos[2]:=
TfrxMemoView(frxReport.
FindObject(‘MVisibleF’));
Campos[0].Font.Style:=
[fsBold];
Campos[0].Font.Size:= 14;
Campos[1].Visible:= True;
Campos[2].Visible:= False;
end;
Veja que criamos um ‘Array’ da mesma classe de nossos componentes de
texto do relatório, ou seja, agora podemos carregar os componentes nessas
variáveis e personalizar da forma que desejarmos. Neste caso deixamos o ca-
beçalho em Negrito e aumentamos sua fonte além de ocultar um dos textos,
veja como deve ficar na imagem abaixo:
Imagem 2 – Relatório personalizado.
janeiro
2015
05
janeiro
2015

Mais conteúdo relacionado

Semelhante a 1501 - Revista - BootStrap.pdf

Informática para concursos téo schah_apostilão_cespe_2012_provas_290_questões...
Informática para concursos téo schah_apostilão_cespe_2012_provas_290_questões...Informática para concursos téo schah_apostilão_cespe_2012_provas_290_questões...
Informática para concursos téo schah_apostilão_cespe_2012_provas_290_questões...IMP Concursos
 
Apostila Power BI Udemy.pdf
Apostila Power BI Udemy.pdfApostila Power BI Udemy.pdf
Apostila Power BI Udemy.pdf
JesseFilipe
 
PPT do Road Show - Infra
PPT do Road Show - InfraPPT do Road Show - Infra
PPT do Road Show - Infra
Fabio Hara
 
Trabalho individual 5 semestre Analise de Sistemas
Trabalho individual 5 semestre Analise de SistemasTrabalho individual 5 semestre Analise de Sistemas
Trabalho individual 5 semestre Analise de Sistemas
WANDERSON JONER
 
Integração scratch hotpotatoes moodle and the web
Integração scratch hotpotatoes moodle and the webIntegração scratch hotpotatoes moodle and the web
Integração scratch hotpotatoes moodle and the web
Fernando Rui Campos
 
EuRobo
EuRoboEuRobo
Tele cine mozer
Tele cine mozerTele cine mozer
Tele cine mozer
JBSO
 
Orientações para implementação na rede colaborativa de aprendizagem do uca
Orientações para implementação na rede colaborativa de aprendizagem do ucaOrientações para implementação na rede colaborativa de aprendizagem do uca
Orientações para implementação na rede colaborativa de aprendizagem do ucarositalima
 
Meetup tecnologia - desenvolvimento, infra e processos
Meetup  tecnologia - desenvolvimento, infra e processosMeetup  tecnologia - desenvolvimento, infra e processos
Meetup tecnologia - desenvolvimento, infra e processos
Guilherme Veras
 
Como Acessar Ambiente de Treinamento SAP? [COMPLETO]
Como Acessar Ambiente de Treinamento SAP? [COMPLETO]Como Acessar Ambiente de Treinamento SAP? [COMPLETO]
Como Acessar Ambiente de Treinamento SAP? [COMPLETO]
Leonardo Ribeiro
 
WordPress para sua empresa
WordPress para sua empresaWordPress para sua empresa
WordPress para sua empresa
Sambeleleny Chicupo
 
Joomla daydf construindo um templare 2.0
Joomla daydf   construindo um templare 2.0Joomla daydf   construindo um templare 2.0
Joomla daydf construindo um templare 2.0
Raphael França
 
Consultores Digitais semana 1 dia 4 (participantes)
Consultores Digitais semana 1 dia 4 (participantes)Consultores Digitais semana 1 dia 4 (participantes)
Consultores Digitais semana 1 dia 4 (participantes)
Bootcamp Consultores Digitais
 
Portifolio segundo semestre UNOPAR
Portifolio segundo semestre UNOPARPortifolio segundo semestre UNOPAR
Portifolio segundo semestre UNOPAR
gelolima
 
Google Update Page Experience - RD Hostel
Google Update Page Experience - RD HostelGoogle Update Page Experience - RD Hostel
Google Update Page Experience - RD Hostel
Seo Martin
 
Relatorio_Final_TCC1_Bruno_dos_Anjos_Silveira
Relatorio_Final_TCC1_Bruno_dos_Anjos_SilveiraRelatorio_Final_TCC1_Bruno_dos_Anjos_Silveira
Relatorio_Final_TCC1_Bruno_dos_Anjos_SilveiraBruno Dos Anjos Silveira
 
8 motivos-para-usar-o-yii2
8 motivos-para-usar-o-yii28 motivos-para-usar-o-yii2
8 motivos-para-usar-o-yii2
Renato Lucena
 
Documentação Influentio | Implantação Social Box
Documentação Influentio | Implantação Social BoxDocumentação Influentio | Implantação Social Box
Documentação Influentio | Implantação Social Box
influentio
 

Semelhante a 1501 - Revista - BootStrap.pdf (20)

Informática para concursos téo schah_apostilão_cespe_2012_provas_290_questões...
Informática para concursos téo schah_apostilão_cespe_2012_provas_290_questões...Informática para concursos téo schah_apostilão_cespe_2012_provas_290_questões...
Informática para concursos téo schah_apostilão_cespe_2012_provas_290_questões...
 
Ger301
Ger301Ger301
Ger301
 
Apostila Power BI Udemy.pdf
Apostila Power BI Udemy.pdfApostila Power BI Udemy.pdf
Apostila Power BI Udemy.pdf
 
PPT do Road Show - Infra
PPT do Road Show - InfraPPT do Road Show - Infra
PPT do Road Show - Infra
 
Trabalho individual 5 semestre Analise de Sistemas
Trabalho individual 5 semestre Analise de SistemasTrabalho individual 5 semestre Analise de Sistemas
Trabalho individual 5 semestre Analise de Sistemas
 
Integração scratch hotpotatoes moodle and the web
Integração scratch hotpotatoes moodle and the webIntegração scratch hotpotatoes moodle and the web
Integração scratch hotpotatoes moodle and the web
 
EuRobo
EuRoboEuRobo
EuRobo
 
Tele cine mozer
Tele cine mozerTele cine mozer
Tele cine mozer
 
Orientações para implementação na rede colaborativa de aprendizagem do uca
Orientações para implementação na rede colaborativa de aprendizagem do ucaOrientações para implementação na rede colaborativa de aprendizagem do uca
Orientações para implementação na rede colaborativa de aprendizagem do uca
 
Meetup tecnologia - desenvolvimento, infra e processos
Meetup  tecnologia - desenvolvimento, infra e processosMeetup  tecnologia - desenvolvimento, infra e processos
Meetup tecnologia - desenvolvimento, infra e processos
 
Como Acessar Ambiente de Treinamento SAP? [COMPLETO]
Como Acessar Ambiente de Treinamento SAP? [COMPLETO]Como Acessar Ambiente de Treinamento SAP? [COMPLETO]
Como Acessar Ambiente de Treinamento SAP? [COMPLETO]
 
WordPress para sua empresa
WordPress para sua empresaWordPress para sua empresa
WordPress para sua empresa
 
Html5 ass
Html5 assHtml5 ass
Html5 ass
 
Joomla daydf construindo um templare 2.0
Joomla daydf   construindo um templare 2.0Joomla daydf   construindo um templare 2.0
Joomla daydf construindo um templare 2.0
 
Consultores Digitais semana 1 dia 4 (participantes)
Consultores Digitais semana 1 dia 4 (participantes)Consultores Digitais semana 1 dia 4 (participantes)
Consultores Digitais semana 1 dia 4 (participantes)
 
Portifolio segundo semestre UNOPAR
Portifolio segundo semestre UNOPARPortifolio segundo semestre UNOPAR
Portifolio segundo semestre UNOPAR
 
Google Update Page Experience - RD Hostel
Google Update Page Experience - RD HostelGoogle Update Page Experience - RD Hostel
Google Update Page Experience - RD Hostel
 
Relatorio_Final_TCC1_Bruno_dos_Anjos_Silveira
Relatorio_Final_TCC1_Bruno_dos_Anjos_SilveiraRelatorio_Final_TCC1_Bruno_dos_Anjos_Silveira
Relatorio_Final_TCC1_Bruno_dos_Anjos_Silveira
 
8 motivos-para-usar-o-yii2
8 motivos-para-usar-o-yii28 motivos-para-usar-o-yii2
8 motivos-para-usar-o-yii2
 
Documentação Influentio | Implantação Social Box
Documentação Influentio | Implantação Social BoxDocumentação Influentio | Implantação Social Box
Documentação Influentio | Implantação Social Box
 

1501 - Revista - BootStrap.pdf

  • 3. janeiro 2015 03 20 Índice Dicas The Club 30 Editorial 04 10 Autor: Hamden Vogel 05 Autor: Marlon Aparecido Branco Valentino 26 Delphi - Gerador de Tabelas e Consultas através de um parser SQL - parte II Autor: Thiago C. Montebugnoli Autor: Luciano Pimenta Bootstrap – Uma ideia geral sobre este Framework Android Studio - Volley SQL Server – Explorando recursos para Importação e Exportação de Dados
  • 4. janeiro 2015 04 Delphi é marca registrada da Borland International, as demais marcas citadas são registradas pelos seus respectivos proprietários. Thiago Montebugnoli- Editor Chefe thiago@theclub.com.br Caro amigo, Primeiramentegostariadedesejarumótimoiníciodeanoequenossaparceria continue a mesma por toda esta nova caminhada. Nestaedição,nossocolunistamensalLucianoPimenta,continuaabordandoo usodoAndroidStudio.Elenosensinaautilizarumabibliotecaparatrabalharcom oprotocoloHTTP,denominadaVoley.AmesmafazrequisiçõesWEBparatrabalhar comdadosJSONouimagens,sendoumadasmaisindicadaspelasuapraticidade evelocidade.JáNossoConsultorMarlonAparecidoBrancoValentinoéoautordo artigo“Bootstrap–umaideiageralsobreesteframework”.Comooprópriotítulo indica,elenos orienta e apresenta alguns dos principais recursos desta poderosa ferramenta “front-end”, agilizando e aplicando diversas funcionalidades com um volume de trabalho muito baixo. Eu transformei uma dica em um pequeno artigo que explora um dos recursos do SQL Server, a importação e exportação de Dados utilizando o “SQL Server Integration Services”, uma ferramenta altamente recomendada para executar operações de Extração, Transformação e Carga de Dados envolvendo inúmeras plataformas. Já nosso colaborador Hamden Vogel, na segunda parte do artigo sobre o “Gerador de Tabelas e Consultas através de umParserSQL”discutemaisalgunsmétodossobreestainteressanteferramenta, procurando sempre desenvolver de uma forma abstrata se tornando mais uma alternativa de execução de comandos SQLs para o componente ClientDataSet e seus descendentes. Não esqueça de dar uma conferida em nossa seção de Dicas e Truques. Desejo a todos uma boa leitura e até o mês que vem! Abraços Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150 Informações e Suporte: (14) 3732-1529 Internet http://www.theclub.com.br Cadastro: cadastro@theclub.com.br Suporte: suporte@theclub.com.br Informações: info@theclub.com.br Skype Cadastro: theclub_cadastro Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3 www.twitter.com/theclubbr Copyright The Club 2013 Diretor Técnico Marcos César Silva Diagramação Vitor M. Rodrigues Design Vitor M. Rodrigues Revisão Denise Blair Colunistas Hamden Vogel Jeferson Silva de Lima Luciano Pimenta Lucas Vieira de Oliveira Thiago Cavalheiro Montebugnoli Impressão e acabamento: GRIL - Gráfica e Editora Taquarituba-SP - Tel. (14) 3762-1345 Reprodução A utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais. Editorial
  • 5. janeiro 2015 05 Introdução Naépoca emque estamos à áreade desenvolvimento de aplicativos para web e mobile está trabalhando para entregar os melhores produtos, com isso os prazos que estão cada vez mais curtos, logo precisamos de um framework front-end que, ao mesmo tempo, agilize e facilite o desenvolvimento, e basta pesquisar um pouco que encontrará dezenas deles. O Bootstrap está entre os melhores, criado pelos desenvolvedores do Twitter, é massivamente utili- zado por desenvolvedores e agências ao redor do mundo, pois responde aos requisitos que um desenvolvedor front-end necessita para o mercado atual de softwares para web. ParaquemnãoentendeinglêsaGlobo(http://globocom.github.io/boots- trap/) traduziu a documentação (pois o eles utilizam em projetos internos da empresa),porémaversãoqueelesutilizamestádefasada,emvistaqueaversão atualdoFrameworkBootstrapestánav3.3.1eaversãotraduzidaestánav2.2.2. Quem já é familiarizado com o inglês basta entrar no site oficial do Bootstrap (http://www.getbootstrap.com)quesempreencontraráoFrameworkemsua versão mais atualizada, que apresenta os seguintes recursos: • Designresponsivo,seugridsystemtemcomofoco“mobilefirst”,o layout se adapta ao tamanho da tela do dispositivo móvel, seja ele um celular de 4 polegadas ou um tablete com 8 polegadas (o design responsivo pode ser desativado se necessário); • Conta com um sistema de Grids bem fluido e manipulado simples; • A biblioteca de estilos possui um design moderno para manipular os elementos básicos do HTML, como: buttons, tables, forms, etc; • Ainda possui alguns elementos HTML extras, como: Drop-down, menus de navegação, tanto vertical quanto horizontal, paginação, navegação estrutural, etc; • O JavaScript que acompanha o projeto vem na forma de JQuery plugins, onde o usuário tem alguns elementos adicionais, como: caixas de diálogo, dica de ferramenta, estados de botões, carrossel, etc. OsitedoBootstrapsempreestácomaversãomaisatualizada,paraquem Bootstrap – Uma ideia geral sobre este Framework busca obter a ultima versão basta entrar no site, logo na primeira página já tem um link de download, abaixo do botão de download ele informa a versão atual do framework, como é exibido na imagem 01: Imagem 01. Site. Conhecendo o Framework No site oficial do Bootstrap é possível encontrar vários exemplos que po- demserutilizadoscomaBibliotecafornecidaemseusarquivosCSSeJavaScript. Para quem quer começar a trabalhar com o Framework Bootstrap, a primeira regra para utilizá-lo em seu projeto, é a que ele necessitará de migração para a versão do HTML5(caso não esteja na versão atual da linguagem), porque ele faz o uso de alguns elementos HTML e propriedades CSS que requer o uso do doctype HTML5. Introduzindo alguns elementos do Bootstrap Começando pelo CSS, que pode ser acessado pela parte superior do site naaba‘CSS’,quandoselecionadodirecionaousuárioàpáginaondepodemser encontradosdiversosexemplosdeelementosHTMLaprimoradoseestilizados pelo CSS do framework. Como foi citado anteriormente, o Bootstrap é “mobile first”, que significa Dispositivo móvel em primeiro lugar, o que da preferência ao design respon- sivo. Para assegurar uma representação apropriada da página no dispositivo móvel e o “Zoom” ao toque do usuário, basta adicionar a viewport meta tag
  • 6. janeiro 2015 06 dentro do <head>: <meta name=”viewport” content=”width=device-width, initial-scale=1”> Paradesativaresserecursobastaadicionar“user-scalable=no”naviewport meta tag, use-o com cuidado porque isso pode não agradar muito o usuário, vai ficar igual a linha de código abaixo: <meta name=”viewport” content=”width=device-width, initial-scale=1, maximum- scale=1, user-scalable=no”> Na página do CSS há alguns exemplos de botões utilizando o Bootstrap, para acessar essa parte da página é necessário procurar ao lado direito da páginanomenutemumaopçãochamada“Buttons”eeleexibiráváriasopções de botões, como os da imagem 02 logo abaixo: Imagem 02. Exemplo de Botões. Código do exemplo exibido na imagem 02 está na ordem da esquerda para a direita da imagem: <!-- Botão padrão --> <button type=”button” class=”btn btn-default”>Default</button> <!-- Da peso extra no visual e identifica a primeira acao em um conjunto de botoes --> <button type=”button” class=”btn btn-primary”>Primary</button> <!-- Identifica o sucesso de uma acao ou um comando positivo --> <button type=”button” class=”btn btn-success”>Success</button> <!-- Botao para o contexto da informação de uma mensagem de alerta --> <button type=”button” class=”btn btn-info”>Info</button> <!-- Indica que deve tomar cuidado com a seguinte acao action --> <button type=”button” class=”btn btn-warning”>Warning</button> <!-- Indica perigo ou uma acao negativa --> <button type=”button” class=”btn btn-danger”>Danger</ button> <!-- Tira a enfase de um botão, fazendo-o parecer como um link --> <button type=”button” class=”btn btn-link”>Link</button> Componentes do Bootstrap OBootstraptemdúziasdecomponentesreutilizáveisfeitosparaproviden- ciariconografia,dropdowns,navegação,paginação,alertas,emuitomais.Para ter acesso aos componentes do Bootstrap basta acessar a aba Components do site oficial e será direcionado à página. A Iconografia do Bootstrap é bem simples de utilizar, basta escolher o ícone desejado e copiar o nome da classe referente ao ícone, como mostra a imagem 03 logo abaixo: Imagem 03. Tipos de Icones. Depois utilizá-la na classe do elemento HTML. Na prática o código fonte fica desta maneira: class=”glyphicon glyphicon- star” Exemplo de um Dropdown button mostrado mostrado na imagem 04, quetambémfazpartedoscomponentesreutilizáveisdisponíveisnabiblioteca do framework:
  • 7. janeiro 2015 07 Imagem 04. Exemplo de DropDown. Código do exemplo mostrado na imagem 04 utilizando Bootstrap: <div class=”dropdown”> <button class=”btn btn-default dropdown-toggle” type=”button” id=”dropdownMenu1” data- toggle=”dropdown” aria- expanded=”true”> Dropdown <span class=”caret”></span> </button> <ul class=”dropdown- menu” role=”menu” aria- labelledby=”dropdownMenu1”> <li role=”presentation”><a role=”menuitem” tabindex=”-1” href=”#”>Action</a></li> <li role=”presentation”><a role=”menuitem” tabindex=”-1” href=”#”>Another action</a></ li> <li role=”presentation”><a role=”menuitem” tabindex=”-1” href=”#”>Something else here</ a></li> <li role=”presentation”><a role=”menuitem” tabindex=”-1” href=”#”>Separated link</a></ li> </ul> </div> JavaScript UmdosrecursosmaisinteressantesdoframeworkésemdúvidasoJavaS- cript,localizadonaabasuperiordositeescrito“JavaScript”,poiseletrazàvida vários componentes do Bootstrap vários plug-ins JQuery customizados. Eles podemserfacilmenteincluídosemseuprojeto,umporum(utilizandooarquivo “*.js” individual do Bootstrap) ou todos de uma vez (Usando o “bootstrap.js” ou o minimizado “bootstrap.min.js”). Começando pelas janelas modais disponibilizadas pelo framework elas são simplificadas, porém flexíveis, com diálogos prontos que requerem o mínimo de funcionalidade e padrões inteligentes. Na imagem 05 será exibido um exemplo de janela modal estático: Imagem 05. Exemplo de Janelas. Para chamar a janela modal em um botão, por exemplo, é necessário utilizar um identificador dentro da primeira tag <div> que chama a classe “.modal fade”, e o código do botão fica da seguinte maneira: <button class=”btn btn- default” type=”button” data-toggle=”modal” data- target=”#meuModal”> Observe no código abaixo que a primeira tag <div> está com um identi- ficador “meuModal” para o elemento, que é chamado no código do botão a cima, referindo-se à janela modal exibida na imagem 05: <div class=”modal fade” id=”meuModal” tabindex=”-1” role=”dialog” aria- labelledby=”myModalLabel” aria- hidden=”true”> <div class=”modal-dialog”> <div class=”modal-content”> <div class=”modal- header”> <button type=”button” class=”close” data- dismiss=”modal”><span aria- hidden=”true”>&times;</ span><span class=”sr- only”>Close</span></button> <h4 class=”modal- title”>Modal title</h4> </div> <div class=”modal-body”> <p>One fine body&hellip;</p> </div> <div class=”modal- footer”> <button type=”button” class=”btn btn-default” data- dismiss=”modal”>Close</button>
  • 8. janeiro 2015 08 <button type=”button” class=”btn btn-primary”>Save changes</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal --> Outro recurso que é cobiçado pelos usuários do Bootstrap é sem dúvi- das o Carousel(Carrossel em tradução livre), nada mais é do que um “slide” de imagens que circula pelos elementos como um carrossel, se localiza ao lado direito da página JavaScript com o nome Carousel, clicando na opção ele o direcionará para a parte da página que exibe o conteúdo referente ao recurso.O“carrossel”doBootstrapnãoésuportadopelasversõesdo8e9do Internet Explorer, pois o framework utiliza o CSS3 que não é suportado pelas respectivas versões do navegador. Para quem ficou curioso para saber como é funciona o “Carousel” do Bootstrap, logo abaixo na imagem 06 segue um exemplo do recurso: Imagem 06. Exemplo de Carrossel. Este é o código do exemplo mostrado na imagem 06: <div id=”carousel-example- generic” class=”carousel slide” data-ride=”carousel”> <!-- Indicators --> <ol class=”carousel- indicators”> <li data-target=”#carousel- example-generic” data-slide- to=”0” class=”active”></li> <li data-target=”#carousel- example-generic” data-slide- to=”1”></li> <li data-target=”#carousel- example-generic” data-slide- to=”2”></li> </ol> <!-- Wrapper for slides --> <div class=”carousel-inner” role=”listbox”> <div class=”item active”> <img src=”...” alt=”...”> <div class=”carousel- caption”> ... </div> </div> <div class=”item”> <img src=”...” alt=”...”> <div class=”carousel- caption”> ... </div> </div> ... </div> <!-- Controls --> <a class=”left carousel- control” href=”#carousel- example-generic” role=”button” data-slide=”prev”> <span class=”glyphicon glyphicon-chevron-left” aria- hidden=”true”></span> <span class=”sr- only”>Previous</span> </a> <a class=”right carousel- control” href=”#carousel- example-generic” role=”button” data-slide=”next”> <span class=”glyphicon glyphicon-chevron-right” aria- hidden=”true”></span> <span class=”sr-only”>Next</ span> </a> </div> Paraadicionarlegendaàsimagensdoslide,énecessáriocolocardentrode qualquer classe chamada “item” (identifica cada item que compõem o slide) um elemento HTML que ele será alinhado e formatado automaticamente no slide, como é exibido na imagem 07: Imagem 07. Exemplo de Legendas.
  • 9. janeiro 2015 09 O exemplo da imagem 07 foi customizado por mim, é apenas um exem- plar de como ficaria o “carousel“ com uma imagem e legendas, o código da imagem 07 mostra as tags HTML <img> que declara o caminho da imagem, o <h3> responsável pelo titulo da imagem e o <p> pelo subtítulo da imagem, observe o código abaixo: <div class=”item”> <img src=”~/Content/image2/ helix_nebula.jpg” alt=”...” > <div class=”carousel- caption”> <h3>Nebulosa de Hélix</h3> <p>O Olho de Deus</ p> </div> </div> Conclusão ComessaintroduçãoaoFrameworkBootstrapépossívelcomeçarautilizar aferramentadeformabásica,incluindoalgunsdeseusrecursosaseuAplicativo paraweb,comoosexemplosqueforamcitadosnesteartigo.Eparaquemnão suporte@theclub.com.br Marlon Aparecido Branco Valentino Consultor Técnico The Club. Sobre o autor tem conhecimento em desenvolvimento para web e se interessou pela área, recomendo profundamente que comece a estudar linguagens como HTML5, CSS3, JavaScript e JQuery para melhor entender os conceitos do framework e os exemplos presentes no site, já quem possui um conhecimento básico ou avançado em HTML, CSS e JavaScript, também recomendo que estude profundamente o framework Bootstrap, pois além de dar facilitar e agilizar o desenvolvimento,eledaoutracaraaoseuprojeto,sejaeleumalojavirtualou um site empresarial, e com certeza fará a cabeça dos usuários.
  • 10. janeiro 2015 10 O nome pode parecer estranho, mas o Volley é uma biblio- teca HTTP para trabalhar com requisições em aplicações Android. Existem outras maneiras de fazer requisições (Async Task e org.apache), mas a biblioteca da Google é a mais indicada, pois é fácil e principalmente, rápida. Com o Volley, podemos fazer requisições para retornar ou enviar dados JSONebaixarimagens,essasduas,praticamenteasnecessidadesmaiscomuns emaplicaçõesAndroidatualmente.Outravantagem,quenãoprecisamoscriar threads para as requisições (é necessário uma thread separada da principal), o Volley, internamente, cria essa thread na aplicação. Mais informações em: http://developer.android.com/training/volley/ index.html Download e instalação Precisamos instalar a ferramenta Git para baixar a última versão da bi- blioteca. No download deste artigo, está disponível a última, caso não deseje baixar. Baixe a ferramenta em: http://git-scm.com/download/win. A instalação da ferramenta é bem simples. Acesse o Git Bash, que é um prompt de comando, e digite o seguinte código: git clone https://android. googlesource.com/platform/ frameworks/volley Veja na Figura 1 a finalização do download do Volley pelo Git. Android Studio – Volley Figura 1. Baixando o Volley, usando Git O Git vai baixar a biblioteca na pasta do usuário logado no Windows com o nome volley. Agora, precisamos adicionar a biblioteca no Android Studio. Nota: o Android Studio saiu da versão beta. Veja em http://deve- loper.android.com/sdk/index.html a última versão disponível. A Google salienta que o Android Studio é a IDE oficial para Android, não dando mais suporte para plugins de outras IDEs. CrieumnovoprojetonoAndroidStudio.Escolhaqualquertemplate.Após, acesseaestruturadoprojetousandoomenuFile>ProjectStructure(Figura2). Crie no botão de + (New Module). Veja a Figura 2. Estrutura do projeto Android No wizard escolha Import Existing Project (Figura 3) e clique em Next. Veja a Figura 3. Importando um projeto existente
  • 11. janeiro 2015 11 No próximo item, escolha o caminho onde estão os arquivos do Volley (Figura 4). Escolha a raiz do diretório. Clique em Finish. Veja a Figura 4. Escolhendo o diretório do Volley OGradlecomeçaraarecompilaroprojeto.Voltandoateladeestruturado projeto,cliqueemappenaabaDependencies.Nobotãode+,escolhaModule dependency. Será mostrado o módulo adicionado anteriormente (Figura 5). Veja a Figura 5. Configurando o Volley ao nosso projeto Clique em OK e OK. Nota: o Volley necessita da API 19. Caso você não tenha instalado essa API, uma mensagem será mostrada e um link para baixar a API. Também o Build Tools deve ser atualizado com a versão 21. O Android Studio avisa e facilita a instalação. Após, na janela Project temos a pasta do Volley com suas classes incor- poradas ao projeto (Figura 6). Figura 2. Estrutura do projeto Android Figura 3. Importando um projeto existente Figura 4. Escolhendo o diretório do Volley Figura 5. Configurando o Volley ao nosso projeto
  • 12. janeiro 2015 12 Listagem 1. Criando um singleton para RequestQueue Figura 6. Volley adicionado ao projeto O ícone indica que ele é um módulo. Criando o primeiro em exemplo Vamos criar um exemplo simples, para recuperar um JSONObject. Se o seuaplicativofaráusoconstantedeacessoadadosouimagens,éinteressante criar uma única instância do objeto RequestQueue, que tem por finalidade criar as requisições que precisamos. Com uma única instância, será mais rápido criar/chamar as requisições. Vamos criar uma classe conforme a Listagem 1. import android.app.Application; import android.text.TextUtils; import com.android.volley. Request; import com.android.volley. RequestQueue; import com.android.volley. toolbox.Volley; public class AppController extends Application { public static final String TAG = AppController.class. getSimpleName(); private RequestQueue mRequestQueue; private static AppController mInstance; @Override public void onCreate() { super.onCreate(); mInstance = this; } public static synchronized AppController getInstance() { return mInstance; } public RequestQueue getRequestQueue() { if (mRequestQueue == null) { mRequestQueue = Volley.ne wRequestQueue(getApplicationCon text()); } return mRequestQueue; } public <T> void addToRequestQueue(Request<T> req, String tag) { req.setTag(TextUtils. isEmpty(tag) ? TAG : tag); getRequestQueue().add(req); } public <T> void addToRequestQueue(Request<T> req) { req.setTag(TAG); getRequestQueue().add(req); } public void cancelPendingRequests(Object tag) { if (mRequestQueue != null) { mRequestQueue. cancelAll(tag); } } } A classe, controla a “fila” de requisições para o objeto RequestQueue.
  • 13. janeiro 2015 13 Listagem 2. Recuperando dados JSON com Volley No onCreateView (por que criei um projeto com um Fragment), vamos criar o método para recuperar esses dados, conforme a Listagem 2. final TextView mTextView = (TextView)rootView. findViewById(R.id.textView); String url =”http://rest- service.guides.spring.io/ greeting”; final ProgressDialog pDialog = new ProgressDialog(getActivity()); pDialog. setMessage(“Carregando...”); pDialog.setCancelable(false); pDialog.show(); JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request. Method.GET, url, null, new Response. Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { mTextView. setText(“Retorno do WS: “ + response.getString(“content”)); } catch (JSONException e) { Toast. makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG). show(); } pDialog.hide(); } }, new Response. ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast. makeText(getActivity(), error. getMessage(), Toast.LENGTH_LONG). show(); pDialog.hide(); } }); AppController.getInstance(). addToRequestQueue(jsonObjReq); O exemplo é simples, a URL http://rest-service.guides.spring.io/greeting retorna um objeto JSON com dois campos, id e content. A URL foi retirada de umexemplonainternet.OJsonObjectRequestrecebecomoparâmetrootipo de requisição (nesse caso um GET), a URL, um JSONObject e um Listener para o Response e para ErrorResponse. No Response, é onde manipulamos os dados retornados. No ErrorRes- ponse, fechamos o ProgressDialog e também, mostramos uma mensagem, informando o erro. No final, adicionamos a requisição na fila da classe que criamos anteriormente. Podemos ainda, dar uma “tag” para cada requisição, ficando fácil se precisarmos cancelar alguma posteriormente. Temos que “registrar” a classe AppController no AndroidManifest.xml, pois ela será uma classe da aplicação e não de uma Activity, por exemplo. Ela ficará instanciada, enquanto a aplicação estiver rodando. <application android:name=” lasoftwares. myapplication.AppController” android:allowBackup=”true” ... E por fim, precisamos adicionar a permissão de acesso a internet na aplicação Android: <uses-permission android:name=”android. permission.INTERNET” /> Rode a aplicação e veja o retorno da requisição (Figura 7). Figura 7. Retorno da requisição
  • 14. janeiro 2015 14 Listagem 3. Retornando um array de dados com Volley sonArrayRequest O exemplo anterior, é simples, retornamos um JSONObject (assim como poderia ser uma string, usando StringRequest). Mas na maioria dos casos, precisamos retornar vários dados, então, para isso, usamos outro objeto, um JsonArrayRequest. Adicione um ListView na aplicação. O arquivo JSON é de um exemplo da internet, vale apenas para fins didáticos, pois tem apenas dois registros. Na Listagem 3 temos o código para recuperar os dados no ListView. final ListView lv = (ListView) rootView.findViewById(R. id.listView); String url =”http://api. androidhive.info/volley/person_ array.json”; final ProgressDialog pDialog = new ProgressDialog(getActivity()); ... JsonArrayRequest jsonObjReq = new JsonArrayRequest(url, new Response. Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i <= response.length() - 1; i++) { try { JSONObject obj = (JSONObject) response.get(i); list.add(obj. getString(“name”)); } catch (JSONException e) { Toast. makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG). show(); pDialog.hide(); } } lv.setAdapter(new ArrayAdapt er<String>(getActivity(), android.R.layout.simple_ list_item_1, list)); lv.setFastScrollEnabled(true); pDialog.hide(); } }, new Response. ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast. makeText(getActivity(), error. getMessage(), Toast.LENGTH_LONG). show(); pDialog.hide(); } }); AppController.getInstance(). addToRequestQueue(jsonObjReq); O exemplo é bastante semelhante ao anterior, com a diferença que o retorno é um JSONArray e o JsonArrayRequest possui menos parâmetros. Percorremos o retorno da consulta e adicionamos os valores em uma lista de string. Após, preenchemos um ListView com essa lista. Veja na Figura 8, o ListView preenchido. Figura 8. Preenchendo um ListView com o retorno do JsonArrayRequest Trabalhando com parâmetros Muitas vezes, precisamos passar parâmetros para receber o retorno de um JSONObject ou JSONArray. O Volley possui um bug com parâmetros até a última versão que testei, que após várias pesquisas, não encontrei o motivo, mas para contornar o problema, precisamos apenas criar duas classes para
  • 15. janeiro 2015 15 Listagem 4. Criando as classes JsonObjectRequestCustom e JsonArrayRe- questCustom estenderRequestdeJSONObjecteJSONArrayparausarparâmetrosemnossas requisições. Nada muito trabalhoso por sinal. Na Listagem 4 temos o código das duas classes que precisamos criar. JSONObjectRequestCustom import com.android.volley. AuthFailureError; import com.android.volley. NetworkResponse; import com.android.volley. Request; import com.android.volley. Response; import com.android.volley. Response.ErrorListener; import com.android.volley. Response.Listener; import com.android.volley. toolbox.HttpHeaderParser; import org.json.JSONException; import org.json.JSONObject; import java.io.UnsupportedEncod ingException; import java.util.Map; public class JsonObjectRequestCustom extends Request<JSONObject> { private Listener<JSONObject> response; private Map<String, String> params; public JsonObjectRequestCustom(int method, String url, Map<String, String> params, Listener<JSONObject> response, ErrorListener listener) { super(method, url, listener); this.params = params; this.response = response; // TODO Auto-generated constructor stub } public JsonObjectRequestCustom(String url, Map<String, String> params, Listener<JSONObject> response, ErrorListener listener) { super(Method.GET, url, listener); this.params = params; this.response = response; // TODO Auto-generated constructor stub } public Map<String, String> getParams() throws AuthFailureError{ return params; } public Priority getPriority(){ return(Priority. NORMAL); } @Override protected Response<JSONObject> parseNet workResponse(NetworkResponse response) { try { String js = new String(response. data, HttpHeaderParser. parseCharset(response. headers)); return(Response. success(new JSONObject(js), HttpHeaderParser. parseCacheHeaders(response))); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } return null; } @Override protected void
  • 16. janeiro 2015 16 deliverResponse(JSONObject response) throws UnsupportedEncodingException, JSONException { this.response. onResponse(response); } } JSONArrayRequestCustom import com.android.volley. AuthFailureError; import com.android.volley. NetworkResponse; import com.android.volley. Request; import com.android.volley. Response; import com.android.volley. Response.ErrorListener; import com.android.volley. Response.Listener; import com.android.volley. toolbox.HttpHeaderParser; import org.json.JSONArray; import org.json.JSONException; import java.io.UnsupportedEncod ingException; import java.util.HashMap; import java.util.Map; public class JsonArrayRequestCustom extends Request<JSONArray> { private Listener<JSONArray> response; private Map<String, String> params; public JsonArrayRequestCustom(int method, String url, Map<String, String> params, Listener<JSONArray> response, ErrorListener listener) { super(method, url, listener); this.params = params; this.response = response; } public JsonArrayRequestCustom(String url, Map<String, String> params, Listener<JSONArray> response, ErrorListener listener) { super(Method.GET, url, listener); this.params = params; this.response = response; } @Override public Map<String, String> getParams() throws AuthFailureError{ return params; } public Priority getPriority(){ return(Priority. NORMAL); } @Override protected Response<JSONArray> parseNet workResponse(NetworkResponse response) { try { String js = new String(response. data, HttpHeaderParser. parseCharset(response. headers)); return(Response. success(new JSONArray(js), HttpHeaderParser. parseCacheHeaders(response))); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } return null; } @Override protected void deliverResponse(JSONArray response) throws
  • 17. janeiro 2015 17 Listagem 5. Usando parâmetros na requisição Listagem 6. carregando imagens com ImageRequest UnsupportedEncodingException, JSONException { this.response. onResponse(response); } } A ideia é simples, onde atribuímos para a propriedade params, o valor passado dos parâmetros. Vamos adaptar o exemplo do ListView para uma consultacomparâmetros.VejanaListagem5amudançadocódigodoexemplo. ... Map<String, String> params = new HashMap<String, String>(); params.put(“nCdAtividade”, “1”); JsonArrayRequestCustom jsonObjReq = new JsonArrayRequestCustom( url, params, new Response. Listener<JSONArray>() { @Override public void onResponse(JSONArray response) { ArrayList<String> list = new ArrayList<String>(); for (int i = 0; i <= response.length() - 1; i++) { try { JSONObject obj = (JSONObject) response.get(i); ... O código é muito semelhante ao anterior, com a diferença que estamos usando a nossa classe, e possuímos os parâmetros. A URL desse exemplo é de um projeto meu, portanto, não posso passar a mesma, mas o resultado é o retorno dos dados, de acordo com o parâmetro solicitado. Veja na Figura 9, o resultado da consulta (os dados são de testes do meu aplicativo). Figura 9. Preenchendo um ListView com o retorno parametrizado da consulta Imagens com Volley Para carregar imagens usando Volley mostrarei duas maneiras. Podemos usar o ImageRequest de um modo bem simples. Veja na Listagem 6 o código para carregar a imagem em um ImageView (adicione um na aplicação). String url = “http://www. michenux.net/wp-content/ gallery/android/android-256. png”; final ImageView mImageView = (ImageView)rootView. findViewById(R.id.imageView); ImageRequest request = new ImageRequest(url, new Response. Listener<Bitmap>() { @Override public void onResponse(Bitmap bitmap) { mImageView. setImageBitmap(bitmap); } }, 0, 0, null, new Response.ErrorListener() { public void onErrorResponse(VolleyError error) {
  • 18. janeiro 2015 18 Listagem 7. Modificando a AppController para usar ImageLoader Listagem 8. Carregando imagens com o ImageLoader //imagem de erro ou mensagem que não pode carregar } }); AppController.getInstance(). addToRequestQueue(request); O ImageRequest necessita do caminho da imagem (URL) e dois Listeners, muito semelhante ao exemplo do JsonObjectRequest. Na primeira execução, dependendo do tamanho da imagem escolhida e sua conexão, a imagem pode demorar a ser exibida. Na segunda execução, a imagem é mostrada mais rapidamente. Caso queira mostrar para o usuário o carregamento, use o mesmo exem- plo do ProgressDialog mostrado neste artigo. Veja na Figura 10 a imagem carregada na aplicação. Figura 10. Imagem carregada usando o ImageRequest Outra maneira de carregar imagens, é usando o ImageLoader. Para isso, vamos modificar a classe AppController. Veja na Listagem 7 as modificações. private ImageLoader mImageLoader; ... @Override public void onCreate() { ... mImageLoader = new ImageLoader(getRequestQueue(), new ImageLoader.ImageCache() { private final LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(20); @Override public Bitmap getBitmap(String url) { return cache.get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { cache.put(url, bitmap); } }); } ... public ImageLoader getImageLoader() { return mImageLoader; } Declaramosumavariávelprivada.NoOnCreate,adicionamosocódigopara instanciar essa variável e o método que retorna a mesma. Para instanciar o ImageLoader,usamosaclasseLruCachequearmazenaaimagememcacheno device. Mais fácil que exemplos onde criamos a classe para o cache. Para carregar a imagem, usamos o código da Listagem 8. final ImageView mImageView = (ImageView)rootView. findViewById(R.id.imageView); ImageLoader mImageLoader = AppController.getInstance(). getImageLoader(); String IMAGE_URL = “http:// fs04.androidpit.info/a/34/82/ android-recyclerview-w-volley- 3482b6-w192.png”; mImageLoader.get(IMAGE_ URL, ImageLoader. getImageListener(mImageView,
  • 19. janeiro 2015 19 R.drawable.ic_default, R.drawable.ic_error)); Pegamos a instância do ImageLoader do AppControler. O get do Image- Loader, recebe como parâmetro a URL da imagem e o getImageListener. No Listener, indicamos o ImageView e duas imagens. A primeira, é para uma imagem padrão e a segunda é para uma imagem de erro. Veja o carregamento da imagem na Figura 11. Figura 11. Carregando imagens com ImageLoader Na imagem padrão, podemos colocar uma com o texto indicando o car- regamento, para que o usuário não pense que a aplicação travou. Caso você tenha pensado em qual maneira usar, para, por exemplo, mostrar imagens em um ListView, indico que a segunda é a que tem a melhor performance. Conclusões Vimos neste artigo, como trabalhar com a biblioteca Volley para fazer re- quisiçõesWebparatrabalharcomdadosJSONouimagens.Éabibliotecamais indicada, pois é desenvolvida pela Google e mais rápida que qualquer outra maneira de fazer requisições em aplicações Android. Migrei meus projetos para o Volley e não me arrependi. Um grande abraço a todos e até a próxima! www.lucianopimenta.net Luciano Pimenta LucianoPimenta(NOVODOMINIO:www.lucianopimenta.com)édesenvolvedorDelphi/C# paraaplicaçõesWebcomASP.NET,WindowscomWin32eWindowsFormscom.NET.Palestrante da 4ª edição da Borland Conference (BorCon) e da 1ª Delphi Conference. É MVP Embarcadero, grupo de profissionais que ajudam a divulgar o Delphi no mundo. Atualmente é desenvolvedor da SoftDesign fábrica de softwares em Porto Alegre-RS. Autor de mais de 90 artigos e de mais de 600 vídeos aulas publicadas em revistas e sites especializados, além de treinamentos presenciais e multimídias. É consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programação e banco de dados. Sobre o autor
  • 20. janeiro 2015 20 C aros leitores, essa edição é a continuação do artigo anterior, discursando sobre o tema de desenvolvimento de um parser SQL para XML persistindo no formato MyBase, podendo claramente ser estendido para stream ou outros formatos possivelmente sem problemas. VimosofuncionamentodeumCRUD(Create/Read/Update/Delete),bem comoacriaçãodeumbancoeseufuncionamento,tudoviaSQLcomolinhade comandoporpartedoaplicativo–nenhumcomandointernodecomunicação com um clientdataset para carregamento e exibição destes dados. Dando continuação, vamos explorar mais a fundo nosso analisador sintá- tico, reprisar alguns conceitos visto que foram reformulados (tanto em telas como no fonte) e discorrer sobre nosso projeto ilustrando o funcionamento básico do mesmo. Figura01–Teladecriaçãodobancodedados,ondeosdadossãoexibidosnagrid viaclientdatasetderetorno;oslistboxesdecolunasevaloressãopopuladosdecorrentes Delphi-GeradordeTabelas eConsultasatravésdeumparser SQL - parte II do filtro do nosso parser em ação. Nesta figura acima vemos que o parser interpretou cada palavra, uma por uma, retirou alguns caracteres como vírgula e aspas (simples e duplas) e fez o tratamento adequado para cada uma delas. Nosso programa faz uso pesadodelistboxesparatratamentoprincipalmentedecampos“chave-valor” (coluna e valores) onde para cada tipo de instrução terá sua implementação adequada, conforme requisitos padrões de SQL (as cláusulas tradicionais de insert, update, etc); Figura 02 – Outro exemplo de criação de um banco de dados chamado “alunos” – e sua exemplificação via componentes do Delphi como os listboxes preenchidos via dataset de retorno do parser. Método Insert
  • 21. janeiro 2015 21 Figura 03 – Tela de Insert – onde o clientdataset recebe o SQL contendo o insert a ser executado e o processa de dentro do aplicativo. OmétodoInsert,DeleteeUpdatefoiexplicadonoitemanterior, deforma sucinta, onde vamos abordar de forma mais ampla o seu funcionamento, a seguir: 1. Existem dois clientdataset´s para o funcionamento do projeto. O primeiro é o clientdataset parser, responsável por extrair a string contendo o SQL para dentro dele, tratando caracteres e outras regras de validação, refinando tratamentos de espaços, espaços dentro de aspas simples, chaves e valores dentro de parênteses, etc; 2. Feito isso, o outro clientdataset receberá ele e com base nele populará os dados em si, e finalmente estará pronto para exibi-los, podendo serem salvos – ou não. Segue o código-fonte do método de gerar insert, responsável por inserir os dados de dentro do projeto para o XML MyBase. procedure TForm1.GerarInsert; var palavra: string; nomeTabelaPassou: Boolean; parametrosPodemInserir: Boolean; i: integer; coluna: string; sqlFiltro: string; //field: TField; begin if not sqlClientDataSetExists then begin Application.MessageBox(‘O Banco não foi criado ainda. Favor voltar na etapa anterior select’ + #13#10 + ‘para que seja criado antes’, ‘Informação’, MB_OK + MB_ICONINFORMATION); Exit; end; if Assigned(sqlClientDataSetS electBase) then sqlClientDataSet := sqlClientDataSetSelectBase; if not tempClientDataSet. Active then Exit; if (tempClientDataSet. RecordCount = 0) then Exit; ListBox2.Items.Clear; ListBox3.Items.Clear; nomeTabelaPassou := False; sqlClientDataSet.Filtered := False; tempClientDataSet.First; while not tempClientDataSet. Eof do begin palavra := AnsiUpperCase(tempClientDataSet. FieldByName(‘TEXTO’).AsString); if (palavra <> ‘INSERT’) and (palavra <> ‘INTO’) and (palavra <> ‘VALUES’) then begin if parametrosPodemInserir then begin if parametrosPodemInserir then ListBox3.Items. Add(StringReplace(palavra, chr(39), ‘’, [rfReplaceAll])); end else begin if nomeTabelaPassou then ListBox2.Items. Add(palavra); nomeTabelaPassou := true; end; end; if (AnsiUpperCase(palavra)
  • 22. janeiro 2015 22 = ‘VALUES’) then parametrosPodemInserir := true; tempClientDataSet.Next; end; for i := 0 to ListBox2.Count - 1 do begin if i = 0 then sqlFiltro := sqlFiltro + ListBox2.Items.Strings[i] + ‘=’ + QuotedStr(ListBox3.Items. Strings[i]) else sqlFiltro := sqlFiltro + ‘ and ‘ + ListBox2. Items.Strings[i] + ‘=’ + QuotedStr(ListBox3.Items. Strings[i]); end; sqlClientDataSet.Filter := sqlFiltro; sqlClientDataSet.Filtered := True; if sqlClientDataSet. RecordCount > 0 then Exit; sqlClientDataSet.Filtered := False; sqlClientDataSet.Insert; for i := 0 to ListBox2.Count - 1 do begin coluna := ListBox2.Items. Strings[i]; if not Assigned (sqlClientDataSet.FieldDefs. Find(coluna)) then begin Application. MessageBox(‘Coluna não encontrada.’, ‘Informação’, MB_ OK + MB_ICONINFORMATION); Exit; end; // field := sqlClientDataSet. fieldByName(coluna); // if not Assigned(field) then continue; sqlClientDataSet. fieldByName(coluna).AsString := ListBox3.Items.Strings[i]; end; sqlClientDataSet.Post; sqlClientDataSet.Close; sqlClientDataSet.Open; end; Persistência ApersistênciaescolhidaparaonossoprojetoédotipoXMLformatomyba- se,salvodeumclientdataset.TodachamadaaumcommitgeraráoarquivoXML com o nome da tabela especificada; se a linha SQL for por exemplo “COMMIT USUARIO” o arquivo “USUARIO.XML” (sim, sempre com letras maiúsculas) será gerado no mesmo diretório em que o projeto estiver rodando. Para esta versão será sempre no mesmo local em que o projeto compile. É claro que evolutivamente poderá ser gerado um stream como saída, ou outras opções de formatos de arquivo, etc; isso não é o foco agora, e sim a ilustração de como funciona o processo. Figura 04 – Tela que exemplifica o processo de salvar e carregar o arquivo XML, que representa o nosso banco de dados, para este nosso projeto. Segue abaixo o código-fonte deste procedimento de gerar a gravação, mais notadamente “gerar o commit”: procedure TForm1. GerarCommit(const sql: string); begin if not sqlClientDataSetExists then Exit; if not sqlClientDataSet. Active then Exit; if sqlClientDataSet.
  • 23. janeiro 2015 23 RecordCount = 0 then Exit; if Assigned(sqlClientDataSetS electBase) then sqlClientDataSet := sqlClientDataSetSelectBase; sqlClientDataSet. SaveToFile(biblioteca. GetNextWord(sql, ‘COMMIT’)+ TableExtension , dfXML); end; Segueafunçãomuitoutilizadaparaobterapróximapalavradeumastring: function GetNextWord(const Str, Find: string): string; var i, k: integer; auxStr: string; begin auxStr := Trim(Str); i := Pos(Find, Str); Result := Trim(Copy(str, i + length(Find), length(str))); k := Pos(‘ ‘, Result); if k > 0 then Result := Trim(Copy(Result, 1, k)); end; Figura05–TeladegeraçãodecommitapartirdalinhadecomandoSQL.Observe quenestareleaseonomedatabelatambéméesperado(“exemplo:commitnome_da_ tabela”) – sendo que nas próximas versões apenas a palavra reservada commit será suficiente, podendo também se utilizada o método anterior. Select´s e mais select´s Agoraparticularmenteumadaspartesmaisinteressantesdoprojeto,que éofiltrodeselect´seseusparâmetros.Oprojetocompreenderáostiposmais famosos, suportados por todos os bancos, e algumas ainda estão por vir nas próximas releases do aplicativo. Vamos destacar os tipos de selects suportados nesta corrente versão: 1. Select * from tabela; 2. Select*fromtabelawherecampo=‘isso’andoutrocampo=‘aquilo’; 3. Select campo, outrocampo, maisumcampo from tabela; 4. Select campo, outrocampo, maisumcampo from tabela where umcamponaocitadoantes = ‘isso’ and maisumoutrocamponaocitadoantes = ‘aquilo’; 5. Select campo as ALIAS1, outrocampo as ALIAS2, maisumcampo as ALIAS3 from tabela; 6. Select campo as ALIAS1, outrocampo as ALIAS2, maisumcampo as ALIAS3 from tabela where umcamponaocitadoantes = ‘isso’ and maisumou- trocamponaocitadoantes = ‘aquilo’; Por enquanto são estes comandos suportados. Está sendo desenvolvido paranovasreleasesoutroscomandospadrõesquerestam,comoporexemplo “Count”, “Top”, “Like”, dentre outros. Vale lembrar que seleções com Joins (left join, right join, inner join, etc) tambémnãoestãoimplementadasnestaversão.Seráimplementadaaindaem versões futuras. No momento são válidas seleções com uma tabela apenas. Figura 06– Tela de select com alias.
  • 24. janeiro 2015 24 Figura 07 – Tela de Select com *. Figura 08 – Tela de select que retorna apenas alguns campos. Figura 09 – Tela de update. Figura 10 – Tela de create table. A tela de criação de tabela (citada acima) permitirá que uma tabela seja criada como nos tipos padrões de banco de dados relacionais (SGBD) – cria- das automaticamente via clientdataset, onde campos not null serão required = false; auto-incremento do tipo AutoInc, chave primária do tipo KeyField = campoChave, e os tipos serão tratados como DataType; segue exemplo do código-fonte abaixo: fDataSet := TClientDataSet(myDataSet); fDataSet.First; if not myClientDataSet.Active then myClientDataSet. CreateDataSet else myClientDataSet. EmptyDataSet; myClientDataSet. DisableControls; try while not fDataSet.Eof do begin myClientDataSet.Insert; for i := 0 to fDataSet. FieldCount - 1 do begin Field := myClientDataSet. FindField(fDataSet.FieldList[i]. FieldName); if Assigned(Field) then
  • 25. janeiro 2015 25 begin K := Field.DataSet. Fields.IndexOf(Field); myClientDataSet. FieldDefs.Items[k].DataType := fDataSet.FieldDefs.Items[i]. DataType; case myClientDataSet. FieldDefs.Items[k].DataType of ftString: myClientDataSet.Fields[k]. AsString := fDataSet.Fields[i]. AsString; ftDate: myClientDataSet.Fields[k]. AsString := Self. DefaultDateFormat2(fDataSet. Fields[i].AsString); ftFloat: myClientDataSet.Fields[k]. AsFloat := Biblioteca. ArredondaComDecimais( fDataSet. Fields[i].AsFloat, 2); ftInteger: myClientDataSet.Fields[k]. AsInteger := fDataSet. Fields[i].AsInteger; else //processa tipos default myClientDataSet. Fields[k] := FDataSet. Fields[i]; end; Conclusão Existem várias formas de se comunicar com sistemas gerenciadores de banco de dados hoje em dia; o que trouxe aqui é um analisador sintático para realizar de forma abstrata mais uma alternativa de execução de sql´s para clientdataset´seseusdescendentes,podendodeformaeficienteseremsalvos e carregados em diferentes customizáveis soluções, no momento a escolhida foi a forma mais natural – a persistência em xml´s, podendo ser estendido para arquivos streams, arquivos binários, ou outros tipos de formatos de arquivos (como por exemplo descendente de TCollection) para a persistência e extração dos dados. Cada tabela será um arquivo, e cada arquivo residirá em um diretório conhecido pela aplicação. No caso todos são locais. Poderá no futuro ser implementado formas de extração de acesso remoto, commits em lock, dentre outros métodos. O projeto estará em constante evolução a cada release e será disponibi- lizado sempre em downloads freewares. Trazer novos tipos de parser SQL para o desenvolvimento Delphi atual- mente é trazer novas ideias de implementação de banco de dados, seja para novos projetos, projetos multi-plataformas, projetos que não necessitem de implementações/instalações “árduas” com inúmeras configurações/mapea- mentoscomdll´s,setup´s,programasexternoscomIDE´sdegeraçãodeSQL´s, etc;trazendoabaixocustomassemperderasegurançaedesempenho–criar soluções confiáveis de manipulação de dados e principalmente exportáveis para outros tipos de formato – que tal o output para um TMemoryStream ou uma customização para um arquivo binário (ou descendente de TStream) onde somente o aplicativo leia seu conteúdo, ou exportação para arquivos baseados em uma implementação de “Memory Mapping Files” (usando CreateFileMappingW) ? É trazer a luz acessos a banco de dados jamais pensados antes, e na troca de informações e de implementações, podendo também ser construído em umWebServicecomJSON,porexemplo,enfim,sãoinúmerasaspossibilidades em que um desenvolvedor tem em suas mãos – o poder da criação. suporte@theclub.com.br Hamden Vogel Analista de Sistemas pós-graduado em Engenharia de Software pela UPIS e Programador Delphi com larga experiência desde 2000, tem de- senvolvido e vendido softwares em Delphi para a África e Estados Unidos, além do mercado nacional. Colaborou com dicas e componentes para sites especializadosemDelphi. Tambémdesenvolveemoutraslinguagenscomo C/C++, ASP, PHP e .NET. Sobre o autor
  • 26. janeiro 2015 26 N este artigo gostaria de abordar um tema muito solicitado em nosso suporte técnico e em geral pela maioria das pes- soas, a exportação e importação de dados. A pergunta que não cala é: Qual a melhor forma para realizar esta tarefa? Na realidade existem diversas maneiras para realizar esta tarefa e ultimamente em meus projetos a que se tornou mais prática e ágil foi a utilização do “SQL Server Integration Services (SSIS)”, uma ferramenta que usamosparaexecutaroperaçõesde“ETL”,ouseja,(E)xtração,(T)ransformação e (C)arga de dados, um dos recursos disponíveis na instalação do Banco de Dados da Microsoft, o SQL Server. Podemos desfrutar deste recurso a partir da versão 2005, mas ressalto que a base deste artigo será redigido na versão do SQL Server Express 2008. Caro leitor, caso não possua o mesmo instalado recomendo a leitura do artigo “Instalando e configurando o SQL Server 2008 Express Edition With Tools” do mês de Março de 2011, que poderá ser encon- trado no nosso site no link abaixo: http://www.theclub.com.br/Restrito/Revistas/201103/inst0311.aspx Características Podemos destacar algumas características, tais como: - Recuperação de dados a partir de diversos tipos de fontes; - Carregar dados em quase qualquer fonte; - Realização de transformações nos dados, como por exemplo de um tipo para o outro. Utilizaremos o assistente de Importação e Exportação de Dados, o que nos ajudará muito. Teremos como base de exemplo a Importação de dados oriundos de uma planilha do Excel (.xls) para uma tabela do banco de dados SQL Server 2008. Descrição das Estruturas A seguir estarei comentando sobre a estrutura desta planilha e da tabela. SQL Server– Explorando recursos para Importação e Exportação de Dados - Planilha do Excel (.xls) Criaremos alguns campos de diversos tipos, Ver sugestão na Imagem 01. Figura 01: Planilha Clientes.xls. - Tabela Clientes Já a tabela de clientes deverá ser idêntica aos tipos de campos da plani- lha abordada acima. Podemos conferir o código para criação da mesma na listagem abaixo. CREATE TABLE [dbo].[Clientes]( [Id_Cliente] [int] NOT NULL, [Nome] [varchar](50) NULL, [Tipo] [varchar](30) NULL, [Ativo] [int] NULL, [Data_Nasc] [date] NULL, CONSTRAINT [PK_Clientes] PRIMARY KEY CLUSTERED ( [Id_Cliente] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ ROW_LOCKS = ON, ALLOW_PAGE_ LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
  • 27. janeiro 2015 27 Criando o Exemplo Para iniciarmos iremos executar o “Importar e Exportar Dados (32 bits)” clicando no menu “Iniciar/Todos os Programas/Microsoft SQL Server 2008”. Ver imagem 02 abaixo: Figura 02: Importar e Exportar Dados. Na tela seguinte nos deparamos com o Assistente de Importação de Exportação de Dados, o qual irá nos auxiliar a criar pacotes para a tarefa em questão. Clique em “Avançar”. Ver Imagem 03. Figura 03: Assistente para Importação e Exportação SQL Server. NapróximatelaescolheremosaFontedeDados,aorigemdaqualosdados devemsercopiados,especificaçãoondeosdadosdeverãosercopiados.Neste caso selecione “Microsoft Excel”, e em “Caminho do Arquivo do Excel”, digite (ou clique no botão ”Procurar”) o caminho da sua planilha a ser exportada, o exemploquecrieiparaesteartigoestácomonomede“Clientes.xlsx”.Devemos também nos atentar para a versão do Excel e checar o item “A primeira linha possui nomes de colunas”. Ver Imagem 04. Figura 04:Origem dos Dados. Após isso aparecerá uma janela para selecionar o Destino, especificação onde os dados deverão ser copiados, que seria o próprio Banco de Dados SQL Server, definindo como: “SQL Server Native Client 10.0”. Na caixa de Diálogo “nome do Servidor” indica onde o mesmo está instalado, como por exemplo: “THIAGO-NOTESQLEXPRESS”.Emautenticaçãouseamesmadainstalaçãodo BD.JáemBancodeDadoslocalizaremosaBasedeDadoscriada.Paraproceder clique no botão “Avançar“, Ver Figura 05. Figura 05: Destino dos Dados. Na próxima tela, dentre as duas opções disponíveis, deveremos escolher a “copiar dados de uma ou mais tabelas ou exibições”. Ver Imagem 06. Figura 06: Especificar Cópia ou Consulta de tabela.
  • 28. janeiro 2015 28 Já na próxima etapa irão aparecer as opções para criação ou utilização de tabelas com base nas planilhas, Ver Figura 07. Figura 07: Tabelas e Exibições. Dandoumduplocliquenaopçãodaplanilhaouselecionandoumaclicando no botão “Editar Mapeamentos…”, aparecerá a seguinte janela, onde você irá definir os tipos de dados de cada campo, bem como suas propriedades (se permite valores nulos, tamanho, etc). Nesta mesma janela ao clicar no botão “Editar SQL…”, teremos a possibilidade para editar a instrução para criação da tabela na base de dados. Após isso, clique em OK até retornar à janela que está o botão “Editar Mapeamentos…”. No botão “Visualização”, poderemos consultar os registros da planilha a serem inseridos no SQL Server. Clique em “Avançar” para continuar. Ver Imagem 08. Figura 08: Mapeamentos de Colunas. Nas próximas etapas o assistente nos permite revisar todo Mapeamento de Tipo de Dados, selecionando a tabela para verificar como seus tipos de dados são mapeados para aqueles no destino. Além disso, podemos escolher o modo como o assistente lida com problemas de conversão. Ver figura 09. Veja a Figura 09:Revisão de Mapeamentos de Tipos de Dados. Após a conclusão teremos um resultado idêntico ao da Figura 10. Figura 10: Execução Concluída. Ao abrir a tabela importada no SSMSS (SQL SERVER MANAGEMENT STU- DIO EXPRESS) e visualizá-lo, tereemos todos os registros da tabela mostrados
  • 29. janeiro 2015 29 abaixo: Ver Imagem 11. Figura 11: Resultado da Consulta SQL Server. Conclusões Vimos neste artigo o uso prático de um dos recursos presentes no SQL Server, o “SQL Server Integration Services (SSIS)”. Aprendemos com base na importação de uma planilha do Excel para uma tabela do SQL Server, mas ressalto que temos diversas possibilidades como: .Net Frameworks Data Providers (Dbexpress, ODBC, Oracle, SQL Server, etc...), Microsoft Access, Microsoft OLE DB (Analysis Services, Data Mining, OLAP, Oracle, etc..). Uma informação importante que não podia deixar de salientar é que a primeira Figura 09:Revisão de Mapeamentos de Tipos de Dados. versãodoSSISfoilançadacomoSQLServer2005.SSISéumasubstituiçãopara oDataTransformationServices(DTS),queestavadisponívelcomoSQLServer 7.0 e SQL Server 2000. SSIS baseia-se nas capacidades introduzidas com DTS. Fica aí a dica, um abraço a todos e até o mês que vem! thiago@theclub.com.br Thiago Cavalheiro Montebugnoli adora aprender novas tecnologias. Formado pela Faculdade de Tecnologia de Botucatu – SP (FATEC), já desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Atualmente trabalha no Centro de Processamento de Dados da Prefeitura Municipal de Itaí-SP é colunista mensal da Revista The Club Megazine e é consultor Técnico do The Club. Possui as seguintes certificações: MCP - Microsoft Certified Professional, MCTS-MicrosoftCertifiedTechnologySpecialist,MCAD-MicrosoftCertifiedApplicationDeveloper e MCSD - Microsoft Certified Solution Developer. Sobre o autor
  • 30. janeiro 2015 dicas the club 30 Listagem 1 – Exibir Relatório. Listagem 2 – Evento OnBeforePrint. FastReport Nesta dica vamos utilizar o evento ‘OnBeforePrint’ do ‘frxReport’ para personalizarmos nosso relatório. Inicialmente veremos a codificação para chamar o relatório em tela: frxReport.ReportOptions.Name := ‘ The-Club ‘; frxReport.PrintOptions.Printer := ‘ Nome da Impressora ‘; frxReport.PrepareReport; frxReport.ShowReport; Imagem 1 – Relatório. Temos 3 ‘TfrxMemoView’ adicionados a uma banda ‘Title’ vamos alterar de acordo com codificação abaixo: procedure frxReportBeforePrint(Sender: TfrxReportComponent); Var Campos: Array[0..2] of TfrxMemoView; begin Campos[0]:= TfrxMemoView(frxReport. FindObject(‘MTheClub’)); Campos[1]:= TfrxMemoView(frxReport. FindObject(‘MVisibleT’)); Campos[2]:= TfrxMemoView(frxReport. FindObject(‘MVisibleF’)); Campos[0].Font.Style:= [fsBold]; Campos[0].Font.Size:= 14; Campos[1].Visible:= True; Campos[2].Visible:= False; end; Veja que criamos um ‘Array’ da mesma classe de nossos componentes de texto do relatório, ou seja, agora podemos carregar os componentes nessas variáveis e personalizar da forma que desejarmos. Neste caso deixamos o ca- beçalho em Negrito e aumentamos sua fonte além de ocultar um dos textos, veja como deve ficar na imagem abaixo: Imagem 2 – Relatório personalizado.