quarta-feira, 2 de outubro de 2013

Palestra online sobre MEAN (MongoDB, ExpressJS, AngularJS e Node.js) - amanhã (03/10), às 13:00h (BRT)

Amanhã (03/10) será transmitida uma palestra online sobre MEAN - um acrônimo que representa uma pilha de tecnologias para desenvolvimento Web (MongoDB, ExpressJS, AngularJS e Node.js).

O primeiro palestrante será Valeri Karpov (do MongoDB), que cunhou o termo "MEAN". Ele explicará porque selecionou essas tecnologias e porque outros desenvolvedores deveriam fazer o mesmo. Depois, Ward Bell (da IdeaBlade) falará um pouco sobre a utilização do BreezeJS para lidar, de maneira simples, com os dados de aplicações de grande porte. Por fim, palestrantes da StrongLoop falarão sobre como aplicar o MEAN em ambientes mobile empresariais.

Acompanhe a palestra abaixo:



Perguntas poderão ser feitas após o evento nesse link.


"MEAN is a full app development stack including MongoDB, ExpressJS, AngularJS and node.js.  In this hour we'll visit with Valeri Karpov of MongoDB who first coined the term.  He'll cover background on why he selected these components and why other developers might choose the same stack.  From there, we'll chat with Ward Bell from IdeaBlade discussing how BreezeJS makes managing data simpler in large applications.  Our last speakers are from StrongLoop.  They'll present on how MEAN can work for mobile enterprise environments.  We'll end with a short Q&A."


sexta-feira, 16 de agosto de 2013

Sass - Indo Além do CSS

Sass é uma meta-linguagem do CSS (construída sobre o CSS) que é utilizada para descrever o estilo de um documento de maneira estruturada e legível, provendo mais poder que um CSS tradicional. 

O Sass provê uma sintaxe mais simples e elegante para o CSS e implementa diversas funcionalidades que são úteis para se criar estilos mais fáceis de serem mantidos e adaptados.

Bom, mas a melhor forma de entender o que é o Sass é vendo seu funcionamento na prática, então vamos ao que interessa!


Instalando o Sass

Antes de mais nada, a primeira coisa a se fazer é instalar o Sass na máquina de desenvolvimento e, para isso, é necessário ter o Ruby já instalado (o Sass é uma "gema", ou seja, uma aplicação feita em Ruby).

Obs.: No Mac OS, o Ruby já vem instalado por padrão. Já no Windows e no Linux, é necessário fazer a sua instalação - no caso do Linux, usar o package manager; no caso do Windows, o instalador pode ser baixado aqui (marcar a opção para incluir o diretório "bin" no PATH do sistema).

Para verificar se o Ruby está corretamente instalado, execute o comando "ruby -v", que retornará no console a versão que está rodando.

Para instalar o Sass, basta executar o comando abaixo no console.
gem install sass

Criando o primeiro arquivo SCSS

O Sass trabalha com arquivos com a extensão "scss". Esses arquivos, se estiverem sendo "monitorados" pelo Sass, serão - sempre que alterados e salvos - convertidos automaticamente em arquivos ".css" correspondentes. Os arquivos ".css" é que serão interpretados pelo navegador, como de costume.

Dessa forma, o desenvolvedor vai criar e alterar apenas os arquivos ".scss", deixar com que o Sass converta esses arquivos e vai então fazer o deploy da aplicação usando apenas os arquivos ".css" que forem gerados.

Para fazer o primeiro teste, crie um arquivo "estilos.scss" com um bloco de notas e execute o comando abaixo para que o Sass comece a fazer o seu monitoramento.
sass --watch estilos.scss:estilos.css

O arquivo "estilos.css" será então automaticamente criado e, daqui pra frente, sempre que o arquivo "estilos.scss" for alterado, o arquivo "estilos.css" será imediatamente atualizado.

Para fazer o teste, inclua o conteúdo abaixo no "estilos.scss", salve o arquivo e abra o "estilos.css" para observar seu conteúdo.
#navbar {
  width: 80%;
  height: 23px;
}

Como o que foi inserido é CSS padrão, o arquivo "estilos.css" vai ficar com o mesmo conteúdo (com exceção do fechamento do colchete, que ficará logo após o último ";" - mas isso é configurável no Sass).

Obs.: Para se trabalhar com múltiplos arquivos ao mesmo tempo, pode-se fazer o Sass monitorar um diretório inteiro de arquivos ".scss", sendo gerados os arquivos ".css" em outro diretório, conforme o exemplo abaixo:
sass --watch diretorio_base/sass:diretorio_base/compiled


Conhecendo as funcionalidades do Sass

Bom, até agora geramos um arquivo ".css" utilizando um arquivo ".scss", mas com o conteúdo de um CSS tradicional. Agora, vamos ao que interessa: as funcionalidades que são o diferencial do Sass e fazem com que ele se torne uma ferramenta poderosíssima no apoio ao desenvolvimento de páginas ou sistemas Web.

1. Aninhamento ("Nesting")

Ao escrevermos um CSS, com frequência acabamos tendo que repetir muitos seletores pais. Por exemplo, podemos ter "#navbar ul", "#navbar li" e "#navbar li a", conforme o exemplo abaixo.
#navbar {
  width: 80%;
  height: 23px; 
}
  #navbar ul {
    list-style-type: none; 
  }
  #navbar li {
    float: left; 
  }
    #navbar li a {
      font-weight: bold; 
    }

Para declarar esse conteúdo em um arquivo Sass, sem ter que ficar repetindo os seletores, podemos fazer uso do recurso de aninhamento, conforme pode ser visto abaixo.
#navbar {
  width: 80%;
  height: 23px;
  ul { list-style-type: none; }
  li {
    float: left;
    a { font-weight: bold; }
  }
}

Obs.: Também é possível aninhar propriedades. Por exemplo, com o Sass não é preciso ficar repetindo o "border-", "border-left" e "border-right", como no exemplo abaixo.
.fakeshadow {
  border-style: solid;
  border-left-width: 4px;
  border-left-color: #888;
  border-right-width: 2px;
  border-right-color: #ccc;
}
Ao invés disso, pode-se utilizar o aninhamento, facilitando a leitura e manutenção desse conteúdo:
.fakeshadow {
  border: {
    style: solid;
    left: {
      width: 4px;
      color: #888;
    }
    right: {
      width: 2px;
      color: #ccc;
    }
  }
}

1.1. Pseudo-classes e referência ao pai

Outra coisa comum de ser feita no CSS é utilizar seletores contendo pseudo-classes como ":hover" e ":visited", conforme pode ser visto abaixo.
a {
  color: #ce4dd6;
}
  a:hover {
    color: #ffb3ff;
  }
  a:visited {
    color: #c458cb;
  }

No CSS, cada seletor desses deve fazer referência ao elemento "pai" (o "a", no exemplo acima). Já no Sass, a referência ao seletor pai pode ser substituída pelo caractere especial "&", fazendo-se o aninhamento dos seletores filhos (contendo as pseudo-classes) conforme abaixo.
a {
  color: #ce4dd6;
  &:hover { color: #ffb3ff; }
  &:visited { color: #c458cb; }
}

2. Variáveis

Um recurso interessante do Sass é a possibilidade de declaração de variáveis, que poderão ser reutilizadas muitas vezes na folha de estilos. Uma variável inicia com o caractere "$" e é declarada como se fosse uma propriedade normal do CSS, usando valores de atributos convencionais, conforme o exemplo abaixo.

Arquivo SCSS:
$cor-principal: #ce4dd6;
$estilo: solid;

#navbar {
  border-bottom: {
    color: $cor-principal;
    style: $estilo;
  }
}

a {
  color: $cor-principal;
  &:hover { border-bottom: $estilo 1px; }
}

Arquivo CSS gerado:
#navbar {
  border-bottom-color: #ce4dd6;
  border-bottom-style: solid;
}

a {
  color: #ce4dd6;
}
  a:hover {
    border-bottom: solid 1px;
  }

A grande vantagem de se utilizar variáveis é poder fazer uma alteração (por exemplo, de cor, tamanho ou característica) em um só lugar, e essa alteração se refletir em vários pontos da folha de estilos.

2.1. Operações e Funções

Além da utilização direta de variáveis, é possível utilizar operações matemáticas (+, -, *, / e %) e funções pré-definidas (para cores, números, strings, listas, fazer introspecção, etc) para cálculos dinâmicos de valores de propriedades, conforme o exemplo abaixo.

Arquivo SCSS:
#navbar {
  $navbar-width: 800px;
  $items: 5;
  $navbar-color: #ce4dd6;

  width: $navbar-width;
  border-bottom: 2px solid $navbar-color;

  li {
    float: left;
    width: $navbar-width/$items - 10px;
    background-color: lighten($navbar-color, 20%);
    &:hover {
      background-color: lighten($navbar-color, 10%);
    }
  }
}

Arquivo CSS gerado:
#navbar {
  width: 800px;
  border-bottom: 2px solid #ce4dd6; }
  #navbar li {
    float: left;
    width: 150px;
    background-color: #e5a0e9; }
    #navbar li:hover {
      background-color: #d976e0; }

2.2. Interpolação

Além de serem utilizadas para atribuição de valores de propriedades, as variáveis podem compor o nome de propriedades e seletores, através do uso de "#{}", conforme pode ser observado abaixo.

Arquivo SCSS:
$vert: top;
$horz: left;
$radius: 10px;
.rounded-#{$vert}-#{$horz} {
  border-#{$vert}-#{$horz}-radius: $radius;
  -moz-border-radius-#{$vert}#{$horz}: $radius;
  -webkit-border-#{$vert}-#{$horz}-radius: $radius;
}

Arquivo CSS gerado:
.rounded-top-left {
  border-top-radius: 10px;
  -moz-border-radius-top: 10px;
  -webkit-border-top-radius: 10px; }

3. Mixins

O mixin é um dos recursos mais poderosos do Sass - ele permite o reuso de estilos, ao invés de ficar copiando e colando trechos de código.

Para se criar um mixin, basta usar a diretiva "@mixin", dar um nome para ele, e criar um bloco com os estilos que serão reutilizados. E, para utilizar um mixin, basta usar a diretiva "@include".

Arquivo SCSS:
@mixin rounded-top-left {
  $vert: top;
  $horz: left;
  $radius: 10px;

  border-#{$vert}-#{$horz}-radius: $radius;
  -moz-border-radius-#{$vert}#{$horz}: $radius;
  -webkit-border-#{$vert}-#{$horz}-radius: $radius;
}

#navbar li { @include rounded-top-left; }
#footer { @include rounded-top-left; }

Arquivo CSS gerado:
#navbar li {
  border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px; }

#footer {
  border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px; }

3.1. Utilizando argumentos nos Mixins

O grande poder no uso dos mixins é a possibilidade de criar argumentos para eles. Dessa forma, pode-se passar parâmetros diferentes cada vez que um mixin for utilizado. Além disso, as variáveis declaradas como argumentos podem ter valores padrões, para o caso de não serem passados nenhum valor pra elas.

Arquivo SCSS:
@mixin rounded($vert, $horz, $radius: 10px) {
  border-#{$vert}-#{$horz}-radius: $radius;
  -moz-border-radius-#{$vert}#{$horz}: $radius;
  -webkit-border-#{$vert}-#{$horz}-radius: $radius;
}
#navbar li { @include rounded(top, left); }
#footer { @include rounded(top, left, 5px); }
#sidebar { @include rounded(top, left, 8px); }

Arquivo CSS gerado:
#navbar li {
  border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px; }
#footer {
  border-top-left-radius: 5px;
  -moz-border-radius-topleft: 5px;
  -webkit-border-top-left-radius: 5px; }
#sidebar {
  border-top-left-radius: 8px;
  -moz-border-radius-topleft: 8px;
  -webkit-border-top-left-radius: 8px; }

4. A diretiva @import e os arquivos "partials"

O CSS tradicional já possui a diretiva "@import" para que seja possível quebrar um arquivo de folha de estilos grande em arquivos menores e facilitar a organização e manutenção do código. O problema é que para cada arquivo referenciado em um @import dentro de um CSS é feita uma requisição HTTP separada, o que pode deixar o carregamento da página mais lento.

Dessa forma, no Sass, a diretiva "@import" faz com que as folhas de estilos referenciadas no arquivo SCSS sejam automaticamente injetadas no arquivo CSS gerado. Assim, mantêm-se a organização das folhas de estilo, sem se ter esse overhead a mais no carregamento das páginas.

Esses arquivos importados são chamados de "partials" e, por convenção do Sass, sempre têm seus nomes iniciados por "_".

No exemplo abaixo, o arquivo "estilos.scss" importa o arquivo "_rounded.scss" e o arquivo css correspondente (gerado pelo Sass) vai ser o "estilos.css".

_rounded.scss
@mixin rounded($vert, $horz, $radius: 10px) {
  border-#{$vert}-#{$horz}-radius: $radius;
  -moz-border-radius-#{$vert}#{$horz}: $radius;
  -webkit-border-#{$vert}-#{$horz}-radius: $radius;
}

estilos.scss
@import "rounded";
#navbar li { @include rounded(top, left); }
#footer { @include rounded(top, left, 5px); }
#sidebar { @include rounded(top, left, 8px); }

estilos.css
#navbar li {
  border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px; }

#footer {
  border-top-left-radius: 5px;
  -moz-border-radius-topleft: 5px;
  -webkit-border-top-left-radius: 5px; }

#sidebar {
  border-top-left-radius: 8px;
  -moz-border-radius-topleft: 8px;
  -webkit-border-top-left-radius: 8px; }


Considerações finais

Bom, o que foi apresentado até agora foi apenas um apanhado geral do funcionamento e das principais funcionalidades do Sass. É interessante também dar uma olhada na documentação de referência do Sass para conhecer detalhes do que foi apresentado e mais algumas funcionalidades não citadas nesse post.


Referências utilizadas: grande parte dessas informações foram tiradas do site oficial do Sass, sendo feita uma seleção, tradução, interpretação, organização e complementação com outras informações.


sexta-feira, 12 de julho de 2013

Segundo Evento do GUJavaSC (20/07/2013 - 9:00h)



Segundo evento do Grupo de Usuários JAVA de Santa Catarina.

Dia:  20/07/2013 (sábado) - às 09:00 horas.
Local: Auditório ACATE - Rua Lauro Linhares, 589 - Trindade - Florianópolis.

Inscreva-se através do seguinte formulário: http://bit.ly/121sDiB

Palestra 1: Desenvolvimento Java Web Ágil com Framework Brasileiro

Aprenda como ter uma excelente produtividade aliada à liberdade de criação de layout com esse framework Action Based. Iremos nessa palestra aprender como integrar o VRaptor com jQuery, Bootstrap e AngularJS.

No dia do evento também serão sorteados dois exemplares do eBook "VRaptor: Desenvolvimento ágil para web com Java" e serão distribuídos promocodes de 20% de desconto para aquisição na Casa do Código.

Palestrante: Daniel Kist
Mini-bio:  Programador com 8 anos de experiência em Java e sócio da K2 Studio, onde atua como gerente de projetos e arquiteto de sistemas. Também é contribuidor do projeto VRaptor.

Palestra 2: Dê Seus Primeiros Passos no Desenvolvimento com Android

Nesta palestra serão apresentados os seguintes tópicos: conceitos, estrutura do projeto, gerenciadores de layouts, interface gráfica e como publicar sua app.

Palestrante: Rodolfo Faquin Della Justina
Mini-bio:  Graduado em Sistemas de Informação e entusiasta do Java, trabalha como analista e desenvolvedor Android, atua na análise e gerenciamento de banco de dados no Unibave e como desenvolvedor Android home-office. Possui alguns aplicativos desenvolvidos comercialmente à empresas privadas e também aplicativo publicado na Play Store e Loja da Positivo.

Apoio / Realização:



domingo, 30 de junho de 2013

Os nulos do Objective-C (NULL x nil x Nil x NSNull)


Uma das coisas que chamam bastante atenção de quem inicia no desenvolvimento de aplicações para iOS e começa a aprender a linguagem Objective-C é o grande número de representações de valores nulos.




Dessa forma, pode-se encontrar os nulos sendo declarados das seguintes formas:
  • NULL
  • nil
  • Nil
  • NSNull
Por baixo dos panos, não tem muita diferença entre os três primeiros; mas, por convenção, existem algumas variações sutis e comportamentos particulares são atribuídos a cada um deles.

Assim, ainda em relação aos três primeiros, todos representam valores nulos, ou "zero pointers". A diferença é que "NULL" representa "0" para ponteiros convencionais do C, "nil" é específico para objetos (ou para o tipo abstrato "id"), e "Nil" para ponteiros de classes.

Exemplos de utilização de "NULL":
int *pointerToInt = NULL;
char *pointerToChar = NULL;
struct TreeNode *rootNode = NULL;

Exemplos de utilização de "nil":
NSString *someString = nil;
id someObject = nil;
if (anotherObject == nil) //do something

Exemplos de utilização de "Nil":
Class someClass = Nil;
someClass = [NSString class];

Uma característica "interessante" do Objective-C é que métodos podem ser invocados a partir de objetos "nil" sem que sejam lançadas exceções do tipo "null pointer". Nesse caso, eles apenas retornarão "0" e a aplicação seguirá no seu fluxo normal.

Com isso, aqueles códigos, tipicamente encontrados no Java, que verificam se o objeto é nulo antes de chamar um método, podem ser simplificados, conforme pode ser exemplificado no exemplo abaixo.

Código Java:
if(value && value.isGood()){
    //do stuff with value.
}

Código Objective-C:
if([value isGood]) {
  //do stuff with value. 
}

Dessa forma, se o valor for nulo, o método vai retornar zero e o código dentro do if não será executado.

Obs.: Bom, isso pode ser visto como um benefício, ou como um ponto de risco, já que objetos que representam números (como o NSNumber) também podem ter o valor igual a "0" e, dependendo da situação, não vai ser possível diferenciar se o valor era mesmo nulo, ou se foi atribuído como "0".


Por fim, o "NSNull" é um objeto utilizado para representar o "nil" em situações nas quais não é possível utilizar "nil". Por exemplo, em coleções como o NSSet, o NSArray ou o NSDictionary, não se pode armazenar "nil", então se utilizaria um "NSNull".

Para utilizá-lo, deve-se invocar o método DE classe "null" DA classe "NSNull", conforme o exemplo abaixo. Esse método irá retornar uma instância singleton da classe NSNull".

Exemplo de utilização de "NSNull":
NSNull *nullValue = [NSNull null];
NSArray *arrayWithNull = @[nullValue];
NSLog(@"arrayWithNull: %@", arrayWithNull);
//output: "arrayWithNull: (<null>)"

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:[NSNull null] forKey:@"someKey"];

sexta-feira, 21 de junho de 2013

Lançamento do iOS 7 e do Xcode 5

Na última semana, durante o evento WWDC 2013, que ocorreu na cidade de San Francisco (CA), a Apple anunciou o lançamento do iOS 7 - a última  versão do sistema operacional (SO) da empresa para dispositivos móveis.



Além da aparência, que mudou bastante, o SO trás alguns novos recursos interessantes, dentre eles:
  • Central de Controle (com um gesto de baixo para cima a partir da base, funções de acesso rápido - não configuráveis - são mostradas para o usuário)
  • Multitarefas (navegação nos aplicativos em execução)
  • Melhorias no aplicativo de câmera
  • Air drop (compartilhamento de arquivos, seguindo a linha do MacOS)
  • Melhorias nas notificações (incluindo agora os eventos agendados no calendário)
Mas, como uma imagem vale mas que mil palavras (e um vídeo então, nem se fala!), segue abaixo uma excelente matéria demonstrando essas e outras novas funcionalidades, além de alterações menores nos aplicativos mais comuns (muitas delas visuais e de usabilidade).


Além disso, um outro recurso interessante a ser explorado em projetos de software envolvendo o iOS 7 é o chamado "Nearby Networking with Multipeer Connectivity (P2P)", que possibilita o envio de mensagens, de arquivos e o streaming de dados entre múltiplos dispositivos, utilizando diferentes tecnologias wireless.

A imagem abaixo mostra um dispositivo com BlueTooth habilitado "conversando" com um outro dispositivo com Wi-Fi habilitado, através de um dispositivos que está na mesma região e que tem as duas tecnologias habilitadas.


Vale ressaltar que, por enquanto, apenas uma versão beta do iOS 7 foi liberada para os desenvolvedores e que a liberação da versão oficial para o público geral ainda não tem data definida.

Também já está disponível para download no site da Apple a versão 5 (developer preview) da ferramenta Xcode, que já trás o suporte ao desenvolvimento para iOS 7. As novidades do Xcode 5 em relação à versão 4.6 podem ser vistas aqui.


quinta-feira, 16 de maio de 2013

Nova versão do Android Developer Tools disponibilizada (ADT 22.0.0) e Android Studio saindo do forno

Foi disponibilizada uma nova versão do ADT (Android Developer Tools), a 22.0.0, que pode ser baixada aqui.



Vale ressaltar que tem um novo ambiente de desenvolvimento Android saindo do forno: é o Android Studio. Esse ambiente - diferente do ADT, que é baseado no Eclipse - foi construído sobre a ferramenta IntelliJ IDEA. Uma versão preliminar do Android Studio pode ser baixada aqui.



quarta-feira, 20 de março de 2013

O elemento <svg> do HTML5

O HTML 5 trouxe novas possibilidades em relação a suas versões anteriores. Entre essas novidades está a tag <svg>.

SVG é o acrônimo de "Scalable Vector Graphics" (ou "gráficos vetoriais escaláveis"). É um formato aberto (uma recomendação da W3C) para definir, através da linguagem XML, gráficos bidimensionais baseados em vetores. Esses gráficos podem ser estáticos, dinâmicos e, até mesmo, animados.

DICA: O site svgwow possui diversos exemplos de animações feitas com svg (clique em um dos exemplos e depois no botão "start svg demo").

Uma das grandes vantagens desse tipo de gráfico, em relação a outros formatos de imagem (como JPEG, PNG, GIF, etc), é que ele não perde qualidade quando é redimensionado ou quando é ampliado (zoom), sendo totalmente escalável. Além disso, ele pode ser impresso com alta qualidade, em qualquer resolução.

Por ter uma representação em XML, as imagens SVG podem ser criadas e editadas em qualquer editor de texto (apesar de ser mais simples criá-las em editores, como o Inkscape), além de poderem ser indexadas, buscadas, navegadas (pelo seu DOM) e comprimidas.

No HTML5, podemos criar um gráfico SVG inserindo a tag <svg> dentro de um container HTML tradicional e incluindo dentro dela os elementos relativos à representação gráfica desejada.

DICA: Nessa página, pode-se encontrar uma referência completa de todos os elementos SVG presentes na recomendação do W3C (versão 1.1). E nessa página, pode-se encontrar exemplos de representações do SVG desenhando diferentes formas geométricas e mostrando algumas de suas potencialidades.


A seguir, é apresentado um exemplo de utilização da tag <svg> com a representação da bandeira do Brasil (simplificada), sendo equivalente ao exemplo apresentado no post da tag <canvas> do HTML5.

Visualização:
Ordem e Progresso
*Observação: esse exemplo é suportado pelos navegadores Firefox, Google Chrome, Safari e Internet Explorer a partir da versão 9.

Código fonte:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" height="150" width="250">
   
<rect fill="green" height="150" width="250" style="stroke-width: 1; stroke: rgb(0,0,0);" />

<polygon points="125,0 250,75 125,150 0,75 125,0" style="fill: #FCFF00; stroke-width: 1; stroke: purple;"/>

<circle cx="125" cy="75" fill="#00027F" r="50" stroke-width="1" stroke="black"/>

<rect fill="white" height="15" rx="2" width="100" x="75" y="65"/>

<text fill="black" font-family="Arial" font-size="10" x="80" y="75">Ordem e Progresso</text>

</svg>

DICA: Existem dois tipos de especificações especiais do SVG 1.1 para dispositivos móveis, o "SVG Tiny" (SVGT) e o "SVG Basic" (SVGB). O primeiro é destinado a rodar em máquinas com maior limitação de hardware (como aparelhos celulares) e o segundo a aparelhos com maior capacidade.


<svg> x <canvas>

Conforme pode ser visto no exemplo acima e no exemplo apresentado no post da tag <canvas> do HTML5, muitas vezes pode-se fazer uma imagem SVG equivalente a uma imagem feita em um Canvas. Mas qual a diferença de utilizar uma abordagem ou a outra?

Bom, pra começar, o SVG é baseado em XML - o que implica que todos os seus elementos ficam disponíveis no seu DOM, sendo possível navegar e manipular esses elementos. Também pode-se vincular tratamento de eventos (Javascript) para esses elementos. Além disso, cada forma geométrica é tratada como um objeto e se os atributos desse objeto são alterados, o navegador pode automaticamente renderizar a forma geométrica equivalente. Uma desvantagem dessa abordagem é que, em representações complexas, ele tende a ter uma renderização lenta.

Já na abordagem que utiliza o Canvas, o gráfico é renderizado pixel por pixel e, uma vez que estiver totalmente desenhado, ele é "esquecido" pelo navegador. Assim, qualquer alteração faz com que todo o gráfico tenha que ser desenhado novamente. Além disso, a qualidade do gráfico varia conforme a resolução utilizada. Uma vantagem desse tipo de gráfico é que ele pode ser salvo pelo usuário como uma imagem ".png" ou ".jpg".


O exemplo abaixo, adaptado desse post, deixa bem clara a diferença entre uma imagem tradicional (png) e uma imagem vetorial (svg), ao ser clicado no botão de zoom.


PNG
SVG


Referências


sábado, 9 de março de 2013

Como funciona uma Activity no Android?

Uma atividade é alguma coisa específica que pode ser feita para atingir um objetivo. Em quase todas as atividades ocorre interação com o usuário. Desta forma, em uma aplicação Android, a classe Activity se responsabiliza em criar uma janela, na qual o desenvolvedor pode colocar seus elementos de interface (GUI) através do método "setContentView(View)".

Todo aplicativo Android começa por uma Activity. Quando uma aplicação Android é executada, sua Activity principal (definida como padrão na configuração do projeto) é executada.

Fragments: A partir da versão 3.0 (Honeycomb), as implementações das Activities podem fazer uso da classe Fragment para modularização do seu código - o que também facilita o desenvolvimento de GUIs para telas maiores.

A classe Activity é uma parte importante de todo o ciclo de vida de uma aplicação, e a forma como as atividades são executadas e agrupadas são uma parte fundamental do modelo de aplicação da plataforma.


Ciclo de vida de uma Activity

Uma das questões mais importantes para entender e desenvolver uma aplicação Android é conhecer o ciclo de vida das Activities.

No sistema, as activities são gerenciadas como uma pilha. Quando uma nova Activity é inicializada, ela é colocada no topo dessa pilha e se torna a Activity em execução ("running activity"). A Activity anterior permanece sempre embaixo dela na pilha e não vem para o topo dela ("foreground") enquanto a nova Activity não sai.

O diagrama abaixo, retirado da documentação oficial, apresenta os diferentes estágios em que esse elemento pode se encontrar, além dos eventos que fazem mudar esses estados e dos métodos de callback disparados em cada etapa desse ciclo de vida (retângulos cinzas). Esses métodos podem ser implementados para realização de operações quando uma Activity passa de um estado para outro.


Nesse diagrama, as formas coloridas ovais marcam alguns estágios principais da Activity frente à aplicação, mas pode-se observar também três estados em que uma Activity pode se encontrar após ela ser criada e enquanto a aplicação ainda está rodando:
  1. Activity rodando ou ativa (em foco, no topo da pilha)
  2. Activity pausada (ainda visível, mas sem foco - com outra Activity transparente ou que não ocupe toda a tela na frente dela) 
  3. Activity parada (não visível, com outra Activity na frente)

DICA: Uma Activity pausada está completamente "viva", mantendo todo seu estado e informações e permanecendo ligada ao gerenciador de janelas ("window manager") - ela só será destruída pelo sistema em situações em que a memória ficar extremamente baixa. Já uma Activity parada, também mantém o seu estado e informações, mas sua janela fica oculta e pode ser frequentemente destruída pelo sistema quando for necessário mais memória.

Nos dois casos, o sistema pode destruir as activities "pedindo" para elas finalizarem ou, simplesmente, matando seus processos. Quando elas são apresentadas novamente para o usuário, elas precisam ser completamente reiniciadas e restauradas aos seus estados anteriores.

Ainda nesse diagrama, é possível diferenciar três níveis de ciclo de vida que podem ser analisados e monitorados:
  1. O tempo de vida completo ("entire lifetime"): ocorre desde a primeira chamada ao método "onCreate()" até a chamada do método "onDestroy()".
  2. O tempo de vida visível ("visible lifetime"): ocorre entre uma chamada do método "onStart" e a chamada correspondente do método "onStop()".
  3. O tempo de vida no topo da pilha ("foreground lifetime"): ocorre  entre uma chamada do método "onResume" e a chamada correspondente do método "onPause()".

Dentro do primeiro nível, pode-se enfatizar que uma Activity fará a configuração de todo seu "estado global" dentro do método "onCreate()", e liberá todos os recursos remanescentes no método "onDestroy()". Por exemplo, pode-se criar uma thread para fazer download de dados em backgroud no primeiro método e destruí-la no segundo método.

Dentro do segundo nível, pode-se manter recursos que são necessários ao mostrar a atividade ao usuário. Por exemplo, pode-se registrar um BroadcastReceiver dentro do método "onStart()", para monitorar as mudanças que impactam na GUI, e desregistrá-lo no método "onStop()", quando a tela não está mais visível par ao usuário.

Já dentro do terceiro nível, normalmente se inclui um código leve, já que uma atividade pode alterar frequentemente seu estado entre "resumed" e "paused" - por exemplo, quando o aparelho "dorme" (ao ficar um certo tempo parado), quando o resultado de uma Activity é disponibilizado ou quando um novo Intent é disponibilizado.


Executando uma Activity

Quando uma aplicação Android é executada, a Activity definida como padrão na configuração do projeto é criada automaticamente. De qualquer forma, no código da aplicação, também é possível criar novas Activities.

Para executar outras Activities, basta usar as funções startActivity() ou startActivityForResult().

O método "startActivity()" espera somente um argumento, um objeto da classe Intent, que descreve a atividade que será executada.

Por exemplo, se na nossa Activity principal ("MainActivity") quisermos, já na sua criação (método "onCreate()"), executar uma segunda Activity ("SecondActivity"), podemos fazer da seguinte forma:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Intent i = new Intent(this, SecondActivity.class);  
        startActivity(i); 
 }

    //continuação do código da classe....
}

O segundo método, "startActivityForResult()", é utilizado quando precisamos obter algum resultado da Activity quando ela terminar (por exemplo, pode-se iniciar uma Activity que permite ao usuário selecionar uma pessoa de uma lista de contatos; e, quando ela finalizar, vai retornar a pessoa que foi selecionada).

Esse método espera dois argumentos: um objeto da classe Intent e um número inteiro (para identificar a chamada). O resultado pode ser então obtido através do método "onActivityResult(int, int, Intent)".

Quando uma Activity é finalizada, ela pode chamar o método "setResult(int)" para retornar dados para sua Activity pai. O número inteiro que é parâmetro desse método é o código que identifica o resultado, podendo ser as constantes "RESULT_CANCELED" e "RESULT_OK", ou valores customizados.

Além disso, pode-se retornar um objeto "Intent", contendo qualquer informação desejada. Além do código identificador e do "Intent", o método "onActivityResult" vai receber, na Activity pai, o outro número inteiro que foi fornecido na criação da Activity filha.

DICA: Se uma Activity filha falha, por qualquer razão, a atividade pai recebe um resultado com o código identificado pela constante "RESULT_CANCELED".


No exemplo abaixo, é lançada uma segunda Activity a partir da principal, esperando-se um resultado dela.

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;

public class MainActivity extends Activity {

 static final int PICK_CONTACT_REQUEST = 0;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Intent i = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
        startActivityForResult(i, PICK_CONTACT_REQUEST);
 }
    
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == PICK_CONTACT_REQUEST) {
            if (resultCode == RESULT_OK) {
             //...
            }
        }
    }

    //continuação do código da classe....
}


Referências bibliográficas: grande parte dessas informações foram tiradas da documentação de referência da plataforma Android, sendo feita uma seleção, tradução, interpretação, organização e complementação com outras informações.


segunda-feira, 25 de fevereiro de 2013

O elemento <canvas> do HTML5

O "<canvas>" é um container (uma área retangular) do HTML 5 para desenhar gráficos em tempo de execução, através de scripts (normalmente JavaScript).

O exemplo abaixo ilustra o desenho de um canvas com 100px de largura e 100px de altura, com uma borda de 1px:

Visualização:
Your browser does not support the HTML5 canvas tag.
Código fonte:
<canvas id="meuCanvas1" height="100" width="100" style="border:1px solid #000000;"></canvas>

Dentro desse canvas, é possível desenhar diferentes formas geométricas.

Para desenhar linhas ("paths"), por exemplo, podemos utilizar os métodos "moveTo()" e "lineTo()", conforme o exemplo abaixo:

Visualização:
Your browser does not support the HTML5 canvas tag.
Código fonte:
<script>
//pega uma referência do canvas "meuCanvas"
var c = document.getElementById("meuCanvas");
//pega uma referência pro contexto 2D do canvas
var ctx = c.getContext("2d");
//move o "pincel" para a posição x=0 e y=0 (aqui será o início da linha)
ctx.moveTo(0,0);
//determina a posição final da linha como sendo x=50 e y=75
ctx.lineTo(50,75);
//desenha a linha conforme as coordenadas passadas anteriormente
ctx.stroke();
</script>

Para desenhar um retângulo, podemos utilizar o método "fillRect()", conforme o exemplo abaixo:

Visualização:
Your browser does not support the HTML5 canvas tag.
Código fonte:
<script>
var c = document.getElementById("meuCanvas");
var ctx = c.getContext("2d");
//define a cor de preenchimento
ctx.fillStyle="#0000FF";
//cria um retângulo nas coordenadas x=0 e y=0, de largura 50px e altura 50px.
ctx.fillRect(0,0,50,50);
</script>

Já para desenhar um círculo, podemos utilizar o método "arc()", conforme o exemplo abaixo:

Visualização:
Your browser does not support the HTML5 canvas tag.
Código fonte:
<script>
var c = document.getElementById("meuCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
//o círculo começará a ser desenhado nas posições x=25 e y=25 e terá um raio 10px
ctx.arc(50,50,25,0,2*Math.PI);
ctx.stroke(); //ou ctx.fill() pro círculo ficar pintado
</script>


Além de desenhar formas geométricas, também é possível desenhar textos no canvas, através dos métodos "fillText()" ou "strokeText()", conforme o exemplo abaixo:

Visualização:
Your browser does not support the HTML5 canvas tag.
Código fonte:
<script>
var c = document.getElementById("meuCanvas");
var ctx = c.getContext("2d");
ctx.font="18px Arial";
ctx.fillText("Bom dia! =)",5,50);
</script>


Por fim, utilizando o que já foi apresentado, podemos desenhar a bandeira do Brasil (simplificada), conforme o exemplo abaixo:

Visualização:
Your browser does not support the HTML5 canvas tag.
Código fonte:
<canvas id="myCanvas5" width="250" height="150" style="border:1px solid #d3d3d3;"/>

<script>
var c = document.getElementById("myCanvas5");
var ctx = c.getContext("2d");

//Desenha a retângulo verde
ctx.fillStyle="green";
ctx.fillRect(0,0,250,150);

//Desenha o losango amarelo
ctx.fillStyle = "#FCFF00";
ctx.beginPath();
ctx.moveTo(125,0);
ctx.lineTo(250,75);
ctx.lineTo(125,150);
ctx.lineTo(0, 75);
ctx.lineTo(125,0);
ctx.fill();
ctx.closePath(); 

//Desenha o círculo azul
ctx.beginPath();
ctx.fillStyle="#00027F";
ctx.arc(125,75,50,0,2*Math.PI);
ctx.fill();
ctx.closePath();

//Desenha a faixa branca
ctx.fillStyle="#FFFFFF";
ctx.fillRect(75,65,100,15);

//Desenha o texto
ctx.beginPath();
ctx.fillStyle="#000000";
ctx.font="10px Arial";
ctx.fillText("Ordem e Progresso",80,75);
ctx.fill();
ctx.closePath();

</script>

Bom, esses são apenas algumas questões iniciais sobre o que pode ser feito com o elemento "<canvas>" do HTML 5. Existem muitas questões não abordadas aqui e inúmeros exemplos de desenhos complexos na Web - basta ter interesse e começar a praticar!

segunda-feira, 18 de fevereiro de 2013

Ciclo de vida do Hibernate

O Hibernate é um framework ORM (mapeamento objeto-relacional) - inserindo, removendo ou atualizando registros em tabelas de banco de dados, dependendo de operações feitas sobre objetos de persistência associados a essas tabelas.

Além de abstrair as operações feitas sobre o sistema de banco de dados utilizado, é possível gerenciar os estados dos objetos manipulados pelo framework. Dessa forma, os desenvolvedores devem sempre ter em mente o estado de seus objetos, e não necessariamente a execução de comandos SQL (esse tipo de preocupação aparece mais em processos de "tuning" da aplicação).

Os objetos de persistência manipulados pelo Hibernate possuem 3 estados: "transient", "persistent" e "detached":

  • Um objeto é transiente se ele acabou de ser instanciado (através do operador "new") e não está associado a um objeto "Session" do Hibernate. Ele não tem uma representação na base de dados e nenhum identificador foi associado a ele. Essas instâncias serão destruídas pelo "Garbage Collector" se a aplicação não mantiver mais uma referência para elas.
  • Pessoa pessoa = new Pessoa();
    pessoa.setName("João");
    //objeto Pessoa está no estado 'transient'
    

  • Um objeto persistente tem uma representação na base de dados e um identificador associado a ele. Ele pode ter sido acabado de ser salvo ou carregado e está no escopo do objeto "Session". O hibernate vai detectar qualquer alteração feita no objeto e atualizar a base de dados assim que possível (operação de "flush" dos dados).
  • Long id = (Long) session.save(pessoa);
    //objeto Pessoa agora está no estado 'persistent'
    

  • Um objeto "destacado" ou "separado" foi persistente, mas sua sessão ("Session") foi fechada. A referência para o objeto ainda existe e ele ainda pode ser alterado. Mais tarde, uma instância desse tipo pode ser "religada" a um novo objeto "Session" e suas atualizações podem então ser persistidas novamente.
  • session.close();
    pessoa.setName("João Paulo");
    //objeto Pessoa está no estado 'detached'
    

Obs.: Alguns autores colocam ainda o estado "removido" ("removed") como sendo um quarto estado. Embora possa-se também dizer que o método "delete()" coloque um objeto persistente no estado transiente novamente.

A figura abaixo apresenta os estados descritos e possíveis operações envolvidas nas mudanças de estados.

Não convém, nesse momento, detalhar cada uma dessas operações; mas já se pode ter uma boa noção do ciclo de vida dos objetos de persistência manipulados pelo Hibernate em uma aplicação.

domingo, 10 de fevereiro de 2013

Como gerar automaticamente as tabelas do banco com o Hibernate

O Hibernate possui uma facilidade para criação das tabelas do banco de dados a partir das entidades definidas no modelo da aplicação, é a classe "SchemaExport".

Através dessa classe, pode-se gerar o script DDL para qualquer banco suportado pelo Hibernate, e configurado para ser utilizado por esse framework de persistência.

Segue abaixo um exemplo de uma possível forma de utilizar essa classe.

private void geraTabelas(){
    //AnnotationConfiguration cfg = new AnnotationConfiguration(); //deprecated
    Configuration cfg = new Configuration();
    //Entidades do modelo sendo adicionadas na configuração
    cfg.addAnnotatedClass(Vendas.class);
    cfg.addAnnotatedClass(Clientes.class);
       
    SchemaExport schemaExport = new SchemaExport(cfg);
    schemaExport.create(true, true);
}

O método "create" possui dois argumentos booleanos: o primeiro indica que deseja-se ver o código SQL de geração das tabelas, e o segundo se deseja-se executá-lo (pois pode-se querer apenas visualizar o SQL, para fazer adaptações nesse código ou executá-lo diretamente em um cliente de banco de dados).

Obs.: Lembrando que a versão 4 do Hibernate utiliza a classe "Configuration", ao invés da classe "AnnotationConfiguration", utilizada nas versões anteriores.

Uma questão importante é que, ao rodar esse método, o Hibernate vai fazer executar também um comando SQL "DROP TABLE" com os nomes das tabelas a serem criadas. Se a intenção é apenas atualizar as tabelas com novos campos (relacionados a novos atributos das classes que representam as entidades), deve-se utilizar a classe SchemaUpdate.

sexta-feira, 8 de fevereiro de 2013

Hibernate

No que diz respeito aos frameworks de persistência de dados para Java, o Hibernate - que é uma solução open-source - é hoje em dia um dos mais utilizados, principalmente em se tratando de tecnologias que implementam o padrão JPA. De fato, o Hibernate foi a inspiração para o desenvolvimento da especificação JPA.

De forma geral, o Hibernate pode ser definido como sendo uma ferramenta de mapeamento objeto-relacional*. Essas ferramentas são muitas vezes identificadas pela sua sigla em inglês "ORM" (Object-relational mapping).

De forma simplista, o Hibernate abstrai o código SQL, que é gerado em tempo de execução pelo framework para diferentes bancos de dados. Com isso, ele facilita o desenvolvimento de um sistema orientado a objetos, facilitando também sua legibilidade, manutenção e migração para outros bancos, podendo diminuir o custo dos projetos.

Obs.: Na verdade, hoje em dia, o Hibernate é uma coleção de projetos relacionados, vinculados à comunidade JBoss, que normalmente manipulam modelos baseados em objetos POJO. Dentre esses projetos, o mais clássico é o framework de persistência que está sendo tratado nesse post, o Hibernate ORM (ou, simplesmente, Hibernate). Outros projetos, como o Hibernate Search, o Hibernate Shards, o Hibernate Metamodel Generator, o Hibernate OGM e o Hibernate Validator, também fazem parte dessa coleção de projetos.

No momento em que foi escrito esse post, a versão estável mais atual do Hibernate é a 4.1. A versão 4 possui algumas diferenças em relação à versão 3, que é mais utilizada no mercado; mas essas diferenças serão exploradas em posts futuros.

A última versão do Hibernate pode ser baixada aqui, ou - utilizando Maven - através desse repositório. A documentação oficial (em inglês), tanto da versão 3 quanto da 4, podem ser encontradas aqui.

Bom, nada do que foi dito neste post é novidade, mas a intenção é que ele seja um ponto de início para futuros posts envolvendo o framework Hibernate.

Novos rumos...

2013 chegou, novas metas foram traçadas e esse blog, que estava parado por questões profissionais e acadêmicas, vai voltar à ativa - dessa vez trazendo informações sobre diversas tecnologias utilizadas no desenvolvimento de sistemas para Web e para ambientes móveis.

O blog antes era acessado pelo endereço "flexao.net" e tinha como foco a plataforma Adobe Flex. A partir de agora, utilizando um novo domínio, tratará de desenvolvimento de sistemas em geral, com notícias atualizadas, dicas de programação, melhores práticas, exemplos no estilo "cook-book", apresentação de componentes e discussões gerais, envolvendo diferentes tecnologias utilizadas no desenvolvimento Web e mobile.

Espera-se, com esse espaço, contribuir de alguma forma com a comunidade brasileira de desenvolvedores de sistemas, aprendendo e crescendo junto com os profissionais que fazem parte dela.