Caso prefira, você encontrará todo esse material, em inglês, no site do Developer Android. A tradução e comentários dos materiais eu faço livremente para ajudar a comunidade que fala português.

sexta-feira, 4 de março de 2011

0 comentários

Interface de Usuários - Criando Diálogos

Um diálogo é usualmente uma janela pequena que aparece sobre a atividade corrente. A atividade que roda perde o foco e o diálogo aceita todas as interações do usuário. Diálogos são normalmente usados para notificações que devem interromper o usuário e solicitá-lo a fazer algumas pequenas tarefas diretamente relacionadas com a aplicação em progresso (como uma barra de progresso ou prompt de login).

A classe Dialog é a base para a criação de diálogos. Contudo, você tipicamente não deverá instanciar uma classe Dialog diretamente. Ao invés disso, você deve usar uma das subclasses abaixo:

AlertDialog
Esse diálogo que pode gerenciar nenhum, um, dois ou três botões e/ou uma lista de itens selecionáveis que podem incluir checkboxes ou botões do tipo radio. O AlertDialog é capaz de construir a maioria dos diálogos necessários para a interface e é o tipo de diálogo mais sugerido a que seja usado.

ProgressDialog
É um tipo de diálogo que mostra uma roda ou barra de progresso. Como é uma extensão de AlertDialog, também suporta botões.

DatePickerDialog
É um diálogo que permite ao usuário selecionar uma data.

TimePickerDialog
É um diálogo que permite ao usuário selecionar a hora.

Mostrando um diálogo

Um diálogo sempre é criado e mostrado como parte de uma atividade. Você normalmente vai criar diálogos dentro do método callback onCreateDialog(int). Quando você usa esse método callback, o sistema Android automaticamente gerencia o estado de cada diálogo e se torna o proprietário de cada diálogo. Assim, cada diálogo herda certas propriedades da atividade.

Nota: Se você decidir criar um diálogo fora do método onCreateDialog(), ele não será ligado à atividade. Você pode, contudo, ligá-lo a uma atividade com o método setOwnerActivity(Activity).

Quando você quer mostrar um diálogo, chame showDialog(int) e passe um inteiro que unicamente identifica o diálogo que você quer mostrar.

Quando um diálogo é requisitado pela primeira vez, o Android chama o método onCreateDialog(int) da atividade, que é onde você deverá instanciar a classe Dialog. A esse método callback é passado o mesmo ID que você passou para showDialog(int). Após você criar o diálogo, ele retorna o objeto para o final do método.

Antes do diálogo ser mostrado, o Android também chama um método callback chamado onPrepareDialog(int, Dialog). Defina esse método se você quiser mudar quaisquer propriedades para o diálogo a cada vez que ele for chamado. Esse método é chamado todas as vezes que o diálogo é aberto, enquanto que o onCreateDialog(int) é chamado apenas uma vez, na primeira vez que o diálogo é aberto. Se você não definir onPrepareDialog(), então o diálogo vai manter a mesma configuração que da vez anterior que o abriu. A esse método também é passado o ID do diálogo, juntamente com o objeto Dialog que você criou em onCreateDialog().

A melhor maneira de se definir os métodos callback onCreateDialog(int) e o onPrepareDialog(int, Dialog) é com uma sentença switch que checa o parâmetro id que é passado para dentro do método. Cada case deve checar para um único Id de diálogo. Por exemplo, imagine um jogo onde o usuário tenha dois diálogos diferentes: um para indicar que o jogo está pausado e outro para indicar que o jogo está encerrado. Primeiro, defina uma variável do tipo integer para cada diálogo:

static final int DIALOG_PAUSED_ID = 0;
static final int DIALOG_GAMEOVER_ID = 1;

Então, defina o callback para onCreateDialog(int) com o switch case para cada ID:

protected Dialog onCreateDialog(int id) {
    Dialog dialog;
    switch(id) {
    case DIALOG_PAUSED_ID:
        // Faz o trabalho para definir que o jogo está pausado
        break;
    case DIALOG_GAMEOVER_ID:
        // Faz o trabalho para definir que o jogo encerrou
        break;
    default:
        dialog = null;
    }
    return dialog;
}
Quando é hora de mostrar um dos diálogos, chame showDialog(int) com o ID do diálogo:
showDialog(DIALOG_PAUSED_ID);
Encerrando um Diálogo

Se você quiser encerrar um diálogo, você pode fazê-lo chamando dismiss() no objeto de diálogo. Se necessário, você também pode chamar dismissDialog(int) dentro da atividade, a qual chama dismiss() no diálogo para você.

Se você estiver usando onCreateDialog(int) para gerenciar o estado de seus diálogos, então a cada vez que seu diálogo é encerrado, o estado do objeto de diálogo se mantém com a atividade. Se você decidir que isso não mais necessita do objeto ou que é importante que o estado seja limpo, então você deve chamar removeDialog(int). Esse método vai remover quaisquer referências internas ao objeto e se o diálogo está sendo mostrado, ele vai ser encerrado e desaparecerá da tela.

Usando dismiss listeners

Se você quer que sua aplicação faça algum procedimento assim que o diálogo é encerrado, você deve usar um dismiss listeners no seu diálogo.

Primeiramente defina a interface DialogInterface.OnDismissListener. A interface tem apenas um únido método, onDismiss(DialogInterface), que pode ser chamada quando o diálogo é encerrado. Então simplesmente passe sua implementação de OnDismissListener para setOnDismissListener().

Contudo, note que o diálogo pode também ser cancelado. Esse é um caso especial que indica que o diálogo foi explicitamente cancelado pelo usuário. Isso ocorre quando o usuário pressiona o botão back para fechar o diálogo ou se o diálogo explicitamente chama pelo método cancel() ou, caso exista, o usuário tenha pressionado um botão de cancelamento existente no diálogo. Quando o diálogo é cancelado, o OnDismissListener será notificado, mas se você quiser ser informado que o diálogo foi explicitamente cancelado (e não encerrado normalmente), então você deve registrar um DialogInterface.OnCancelListener com setOnCancelListener().

Criando um AlertDialog


Um alert dialog é uma extensão da classe Dialog. Essa classe é capaz de construir a maioria das interfaces. Você deve usá-lo para diálogos que tenham algumas das seguintes características:
  • Um título
  • Uma mensagem de texto
  • Um, dois ou três botões
  • Uma lista de itens selecionáveis (com checkboxes ou radio buttons opcionais).
Para criar um AlertDialog, use a subclasse de construção AlertDialog.Builder. Consiga um Builder com AlertDialog.Builder(Context) e então use os métodos públicos da classe para definir todas as propriedades do AlertDialog. Após você ter criado o Builder, retorno o objeto AlertDialog com o método create().

Os tópicos do próximo mostrarão como definir várias propriedades de um AlertDialog usando a classe AlertDialog.Builder. Se você usar quaisquer dos códigos seguintes dentro de seu método callback onCreateDialog, você pode retornar o objeto de diálogo resultante para ser mostrar o diálogo.

No próximo post, como adicionar botões, listas, checkboxes e radio buttons. Além disso, também falarei sobre como criar ProgressDialog e CustomDialog.

quinta-feira, 3 de março de 2011

7 comentários

iPad vs Honeycomb (e outros)!


"O que é isso? Uma tabela gigante comparando o novo iPad 2 com os tablets Android Honeycomb, o Touchpad da HP e o Blackberry Playbook? Vendido! Note que alguma das especificações para o Android ainda estão no ar, mas você vai ter uma idéia do que ele é. Tablets Android Honeycomb são muito superiores a qualquer outra coisa nesse universo. Certo? CERTO?"

Traduzido do blog http://www.androidcentral.com (@androidcentral)

Minhas impressões


Antes de dar minhas impressões, eu devo dizer que eu não tenho nada contra o iPad. Tanto é assim que eu mesmo tenho um iPad e estou muito satisfeito com ele. Mas, correndo o risco de ser apedrejado pelos fanboys da Apple por ai, eu digo que me sinto preso.

Ok, meu iPad é jailbroken e eu posso customizá-lo. Mesmo assim continuo me sentindo preso e só posso ir até certo ponto e de lá não passar. Por exemplo, se eu quiser modificar certas características do iOS (ainda na versão 4.2.1) eu posso. Coisas como imagem de tela de fundo, imagem de tela inicial, quais ícones vão ficar na barra, onde os ícones ficarão na tela, se os ícones aparecerão em pastas...

Mas há coisas detestávels e um exemplo é ter de sincronizar as fotos a partir do PC para que eu possa excluir uma única foto, já que não existe essa possibilidade na galeria de fotos. Eu só consigo apagar fotos que eu tenha feito no iPad (ou por algum app que permita que eu crie desenhos e os salve na memória) ou se eu tirar um printscreen da tela. Essas imagens eu posso apagar, mas não consigo fazer a exclusão de fotos que eu fiz sincronização.

Eu só tenho uma opção de navegador que, por enquanto, eu acho que vale a pena usar: o Safari. Existem outros navegadores no ecossistema da Apple que eu posso baixar, mas até onde sei (e posso estar errado), todos usam o engine do Safari, apenas com uma capa diferente. Nesse sentido, eu fico com o original mesmo, já que supostamente não haverá um ganho real de performance na navegação. Cadê o Opera? Cadê o Firefox para iPad? Cadê, e ai seria uma heresia para os fanboys da Apple, o Chrome para iPad? Serei menos limitado quando for lançado o Opera para iPad, que já prometeram. Só que eu quero mais!

Em resumo: é um sistema, na minha muito humilde opinião, fechado demais.

Alguém poderá argumentar que eu posso baixar a partir do Cydia algum app que faça o que eu quero e tudo o mais. E, provavelmente, ele estará certo. Mas ainda assim estarei limitado.

E eu quero mais!

Nesse sentido, os tablets Android Honeycomb são MUITO superiores sim! Aliás, o Android em si. Por exemplo: eu não gosto do meu discador do Xperia X10. E estou falando do discador em sua versão de fábrica, customizado pela Sony Ericsson. Tampouco gosto do discador padrão do Android (que eu já usei quando resolvi fazer o root do meu celular e instalar uma versão Froyo nele, tendo voltado para a versão de fábrica pois até então a captura de vídeo ainda não estava corrigida nessa ROM que instalei). O que vou fazer? Criar um discador customizado para mim e colocar no meu celular. Ponto final. E depois disponibilizar no Market do Android gratuitamente suportado por Adds.

Pergunto: você consegue fazer isso no iOS? Até onde eu sei não. E não acho que esteja errado.

E nem tudo são flores para o mundo Android. O Xoom, por exemplo, ainda não teve o lançamento da versão Wi-Fi confirmado. Eu mesmo não quero comprar uma versão que seja 3G (já bastam as contas que pago de celular). Não posso ter maior capacidade que os 32Gb de fábrica, coisa que o iPad tem desde a 1a versão.

No entanto, o Xoom tem tela de maior resolução - 1280x1024 - comparado a 1024x768 do iPad. Além disso, tem uma densidade maior de 160dpi contra 132dpi do concorrente. Supostamente terá suporte a Flash (que para alguns é importante, não para mim) e terá suporte a cartão microSD.

Bem, a tabela acima fala por si mesma e lá você poderá ver outros aspectos dos tablets comparados ao iPad 2.

Obviamente tem o fato de que a "interface do Honeycomb é um pouco mais complexa que a do iPad e, talvez, mais complicada de usar para algumas pessoas". E aqui estou citando Donald Bell, que fez o review do Motorola Xoom para o CNET (e que comentou isso no podcast Buzz Out Loud).

Mas, qual interface de algum concorrente do gadget da Apple não será mais complicada de se usar? O iPad é simplista, minimalista. Basta um único botão e tudo está resolvido. Como disse em post anterior, minha mãe usa o iPad tranquilamente. E justo ela que não entende patavinas de tecnologia...

Ainda assim, fico com a possibilidade de fazer mais e melhor para as minhas necessidades. E eu, sinceramente, acho que você também vai sentir o quão boa essa liberdade é quando puder fazer o que quiser no Android, assim que todos nós soubermos como programar efetivamente para essa plataforma.

UPDATE 01

Um ponto excelente levantado pelo leitor Mono é o de que "essa tal 'liberdade' que há no Android, muitas vezes é barrada pelo fabricante do aparelho e/ou operadora". Concordo plenamente! Eu mesmo estou escravo do Android 2.1 já que a Sony Ericsson não fará mais updates no meu Xperia X10. Ainda assim, é uma liberdade menos restritiva já que, como o Mono disse também nos comentários, temos uma comunidade que tenta portar as novas versões do celular para aparelhos que não terão mais a atualização oficial.

Então é mesmo o caso de se escolher em qual ambiente restritivo a gente estará: se no ecossistema da Apple ou do Android.

Infelizmente, ambos são restritivos, mas ainda tenho minha convicção que o Android é menos restritivo.

A Apple, em seu SDK, diz que você não poderá criar apps que façam funções que sejam nativas do aparelho. Portanto, criar um app para discador (que eu tenho vontade de fazer para as minhas necessidades), nem pensar. O Android me permite fazer isso.

Outro ponto é que para que meu app seja publicado no iTunes, eu devo mandá-lo para os caras da Apple e, se eles aprovarem, eu terei-o por lá. E essa aprovação pode demorar bastante. No Market é mais fácil publicar seus apps. Em contrapartida, nem todos os apps do Market Android são idôneos e já temos notícias de alguns que vêm com código malicioso, dado que a Google não checa um por um para saber se há algum problema nele.

É uma situação realmente complicada. Mas de mais longe viemos. Lembram-se quando só tinhamos o Nokia e o sistema Symbian dele? Na época era muito mais restritivo, principalmente em termos de hardware.

Mas faço minhas as palavras do Mono (quem quiser saber o que ele disse, basta entrar nos comentários). São comentários muito acertados e que eu realmente deixei de colocar por aqui.

quarta-feira, 2 de março de 2011

1 comentários

Usando StoryBoard como uma ferramenta para programar para Android

Bem, aqui vamos para o StoryBoard. Essa é uma tática que eu uso que nada tem haver com regras já estabelecidas em programação. É algo que eu uso mas vem da minha experiência com outra área, que não vem ao caso agora.

O que é um storyboard?


Segundo a Wikipedia, "StoryBoard são organizadores gráficos tais como uma série de ilustrações ou imagens arranjadas em sequência com o propósito de pré-visualizar um filme, animação ou gráfico animado, incluindo elementos interativos em websites".

O que isso tem haver com programação para Android? Em principio alguém poderia argumentar: nada. Mas, como vocês verão, faz sentido usar storyboards.


Veja a imagem acima. O que um storyBoard faz para a programação para Android é fazer com que você possa visualizar as telas antes de desenhá-las e sentir a necessidade antes de efetivamente escrever uma linha de código. O desenho não está dos melhores. Eu mesmo uso uma folha em branco e vou rabiscando o storyBoard, adicionando itens e apagando-os à medida que vou percebendo a necessidade.

O que dá para se entender a partir dela é a sequência de ações.
  • Se eu clicar no botão MENU, deverá aparecer o menu como mostrado. Se eu clicar no botão BACK a partir dessa tela onde o MENU está presente, ele deverá voltar para a tela anterior.
  • Se eu clicar em Editar a partir da tela inicial ou do MENU, deverá mostrar o nome da tarefa, o campo com o nome escrito e um botão Editar para que seja efetuada a alteração. Ao se clicar em Editar ou clicar no botão Back, volta-se para a tela inicial.
  • Se eu clicar em "-", um botão com a inscrição "-" aparecerá ao lado esquerdo da tarefa. Ao se clicar nesse botão, a tarefa é excluída, mas ainda se continua na tela. Só voltará à tela inicial se for clicado o botão Back.
  • Se eu clicar em "+", a tela onde aparece um campo para eu inserir o nome da tarefa aparecerá e um botão Inserir. Se eu clicar em Inserir ou em Back, volto para a tela inicial.
Como podem ver, é apenas um "mapa" de como a sua aplicação se comportará.

Qual a vantagem dessa visão? Você tem a exata noção de quantas telas terá de desenvolver. Eu desenhei esse storyboard no Visio. Não é a melhor ferramenta mas foi a que eu tive acesso aqui para mostrar a vocês.

Essa é apenas uma maneira que eu uso para me localizar. Obviamente eu poderia fazer toda uma análise do sistema e tudo o mais, usando as mais variadas ferramentas de programação orientada a objeto, fazendo estudos de caso, diagramas, etc. Mas eu preferi tomar uma visão mais minimalistica dado que os seus softwares serão simples, inicialmente. 

Posteriormente será realmente interessante documentar tudo do seu sistema, mas no momento basta ter esse esquema para se guiar na composição da sua aplicação.

Interface de Usuários - Tabs, Navegação Drop-Down e Styling

Adicionando Tabs

A Action Bar pode mostrar tabs que permitem ao usuário navegar entre diferentes fragmentos em uma atividade. Cada tab pode incluir um título e/ou ícone.

Para começar, seu layout deve incluir uma view em que cada fragmento associado com a tab é mostrado. Esteja certo de que a View tenha um ID para ser referenciada no seu código.

Mas o que é fragmento?


De maneira rápida, já que isso será assunto para outro post, o fragmento é um pedaco de uma interface de usuário ou comportamento que pode ser colocado em uma atividade. Ou seja, se antes sua tela era composta apenas por um único XML com todas as informações, agora pode ser quebrada em vários pedaços e juntado, dando maior flexibilidade e reuso das informações.

Para adicionar Tabs na Action Bar:

1. Crie uma implementação de ActionBar.TabListener para lidar com os interações nas tabs da Action Bar. Você deve implementar todos os métodos: onTabSelected(), onTabUnselected() e onTabReselected().

Cada método de callback passa o ActionBar.Tab que recebeu o evento para um FragmentTransaction para que você possa executar a transação do fragmento (adicionar ou remover um fragmento)

private class MyTabListener implements ActionBar.TabListener {
    private TabContentFragment mFragment;
    // Called to create an instance of the listener when adding a new tab
    public TabListener(TabContentFragment fragment) {
        mFragment = fragment;
    }
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        ft.add(R.id.fragment_content, mFragment, null);
    }
    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(mFragment);
    }
    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // do nothing
    }
}
Essa implementação da ActionBar.TabListener adiciona um construtor que salva o fragmento associado com a tab para que cada callback possa adicionar ou remover o fragmento.



2. Capture a Action Bar de sua atividade chamando o método getActionBar() durante o onCreate (mas tenha a certeza de fazê-lo apenas depois que você fez a chamada em setContentView()).

3. Chame setNavigationMode(NAVIGATION_MODE_TABS) para dispobilizar o modo de tab para a ActionBar.

4. Crie cada tab para a Action Bar.

  1. Crie uma nova ActionBar.Tab chamando newTab() na ActionBar()
  2. Adicione um título e/ou ícone para a tab chamando setText() e/ou setIcon().
    Dica: Esses métodos retornam a mesma instância de ActionBar.Tab para que você possa fazer as chamadas em conjunto.
  3. Declare a ActionBar.TabListener a ser usada na tab passando uma instância de sua implementação de setTabListener().
5. Adicione cada ActionBar.Tab para a Action Bar chamando addTab() em ActionBar e passando a ActionBar.Tab.

Por exemplo, o código seguinte combina os passos 2-5 para criar duas tabs e adicioná-las à Action Bar:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
 
    // configura a Action Bar para as tabs
    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
 
    // Remove o título da atividade para dar espaço para as tabs
    actionBar.setDisplayShowTitleEnabled(false);
 
    // Instancia o fragmento na tab
    Fragment artistsFragment = new ArtistsFragment();
 
    // Adiciona uma nova tab e configura seu título e tab listener
    actionBar.addTab(actionBar.newTab().setText(R.string.tab_artists)
            .setTabListener(new TabListener(artistsFragment)));
    Fragment albumsFragment = new AlbumsFragment();
    actionBar.addTab(actionBar.newTab().setText(R.string.tab_albums)
            .setTabListener(new TabListener(albumsFragment)));
}
Todos esses comportamentos que ocorrem quando uma tab é selecionada devem ser definidos por seu método ActionBar.TabListener. Quando uma tab é selecionada, ela recebe a chamada para onTabSelected() e é onde você deverá adicionar o fragmento apropriado para a view designada em seu layout, usando add() com o FragmentTransaction provido. Da mesma maneira, quando uma tab deixa de estar selecionada (quando uma outra tab se torna selecionada), você deve remover o fragmento do layout, usando remove().

Cuidado: Você NÃO deve chamar commit() para essas transações - o sistema faz as chamadas por você e dará uma exceção se você fizer a chamada. Você NÃO pode adicionar essas transações de fragmentos à pilha de processos.

Se sua atividade está parada, você deve guardar a tab seleciona com o estado salvo para que quando o usuário retorne à sua aplicação, você possa abrir a tab. Quando é hora de salvar um estado, você pode conseguir o índice da tab selecionada com getSelectedNavigationIndex(). Esse método retorna o índice de posição da tab selecionada.

Cuidado: É importante que você salve o estado de cada fragmento quando necessário, para que quando o usuário volte para uma determinada tab, ele seja mostrado da maneira como foi deixada. Como fazer essa salva de estado será um tópido dentro do post sobre Fragmentos.

Adicionando Navegação Drop-Down

Como um outro meio de navegação dentro da sua atividade, você pode prover uma lista drop-down em sua Action Bar. Por exemplo, a lista drop-down pode prover modos alternativos para listar o conteúdo da atividade.

Aqui está uma rápida lista de passos para disponibilizar a navegação drop-down:


  1. Crie um SpinnerAdapter que provê a lista de itens selecionáveis para o drop-down e o layout para usar quando desenhar cada item da lista.
  2. Implemente o método ActionBar.OnNavigationListener para definir o comportamento quando o usuário seleciona um item da lista.
  3. Faça com que o modo de navegação esteja disponível para a Action Bar com o método setNavigationMode(). Lembre-se de fazer essa chamada durante o método onCreate. Por exemplo:

    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

  4. Configure o callback do drop-down com setListNavigationCallbacks(). Por exemplo:

    actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
Essa é a configuração básica. Contudo, implementar o SpinnerAdapter e ActionBar.OnNavigationListener faz com que quase todo o trabalho esteja pronto. 

Estilizando a Action Bar

A Action Bar é o cabeçalho de sua aplicação e o ponto de interação primário para os usuários, então você pode querer modificar alguns itens do design para que ele fique mais integrado ao design da sua aplicação. Existem diversas maneiras com as quais você pode fazer isso.

Para modificações simples da sua Action Bar, você pode usar os métodos abaixo:

setBackgroundDrawable()
Configura uma imagem (drawable) para ser usada como a imagem de fundo da Action Bar. A imagem deverá ser do tipo Nine-Patch, do tipo shape e ter uma cor sólida, para que possa ser redimensionada baseado no tamanho da Action Bar. Não use uma imagem bitmap de tamanho fixo.

setDisplayUseLogoEnabled()
Permite o uso de uma imagem alternativa (a logomarca da App) na Action Bar, ao invés do ícone padrão. Uma logomarca é normalmente mais larga, com mais detalhes representando a aplicação. Quando essa opção está disponibilizada, o sistema usa a imagem de logomarca definida na aplicação dentro do arquivo de manifesto, na propriedade android:logo. A logomarca será redimensionada se necessário para se adequar à altura da Action Bar.

A Action Bar tem dois temas padrão: dark e light. O tema dark é aplicado com o tema padrão holográfico, como especificado em Theme.Holo. Se você quer um fundo branco com letras negras, você pode usar Theme.Holo.Light dentro do arquivo de manifesto. 

<activity android:name=".ExampleActivity"
          android:theme="@android:style/Theme.Holo.Light" />

Para mais controle, você pode fazer um override no Theme.Holo ou Theme.Holo.Light e aplicar seus estilos customizados para certos aspectos da Action Bar. Algumas das propriedades da Action Bar que você pode customizar incluem:

android:actionBarTabStyle
Estilo para as tabs na Action Bar

android:actionBarTabBarStyle
Estilo para a barra que aparece abaixo das tabs na Action Bar

android:actionBarTabTextStyle
Estilo para o texto nas tabs

android:actionDropDownStyle
Estilo para o drop-down usado no meu flutuante e navegação drop-down.

android:actionButtonStyle
Estilo para a imagem de fundo usada para botões na Action Bar.

android:windowActionBar
Configure a propriedade para false para remover a Action Bar

android:windowNoTitle
Configure a propriedade para true para também remover a barra de título tradicional

terça-feira, 1 de março de 2011

4 comentários

Interface de Usuários - Usando a Action Bar

A Action Bar é um widget para atividades que substitui a barra de títulos tradicional do topo da tela (mas apenas para dispositivos com Android 3.0). Por padrão, a Action Bar inclui o logo da aplicação à esquerda, seguido pelo título da atividade e quaisquer outros itens disponíveis do menu de opções no lado direito. A Action Bar oferece muitas características úteis, incluíndo a habilidade de:
  • Mostrar itens do menu de opções diretamente na Action Bar, como itens de ação - Action Items - provendo acesso instantâneo às ações do usuário.
    Os itens de menu que não aparecem como itens de ação são colocados num menu flutuante, que é revelado por uma lista drop-down.
  • Provê tabulação para navegar entre fragmentos.
  • Provê uma lista drop-down para navegação.
  • Provê Action Views em local de itens de ação.
Screenshot de uma Action Bar na aplicação de email,
contendo os itens de ação para compôr novos emails e outros.

Adicionando a Action Bar

A Action Bar é incluída por padrão em todas as atividades cujo alvo é o Android 3.0 ou superior. Mais especificamente, todas as atividades que usam o novo tema "holographic" incluem o Action Bar e qualquer aplicação cujo alvo seja o Android 3.0 recebe automaticamente esse tema. Uma aplicação é considerada como tendo alvo a versão 3.0 quando o atributo android:minSdkVersion ou androd:targetSdkVersion dentro do elemento <uses-sdk> tem como valor o número 11 ou maior.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.helloworld"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="4"
                     android:targetSdkVersion="11" />
    <application ... >
        ...
    </application>
</manifest>

Nesse exemplo, a aplicação requer uma versão mínima da API Level 4 (Android 1.6) mas também tem como alvo a versão API Level 11 (Android 3.0). Dessa maneira, quando a aplicação é instalada em um dispositivo rodando Android 3.0+, o sistema aplica o tema holográfico para cada atividade e então cada atividade incluirá a Action Bar.

Contudo, se você quer usar a API da Action Bar, como adicionar tabs ou modificar estilos da Action Bar, você precisar colocar o atributo android:minSdkVersion para "11".

Removendo a Action Bar

Se você quer remover a Action Bar por qualquer razão, configure o tema para Theme.Holo.NoActionBar. Por exemplo:
<activity android:theme="@android:style/Theme.Holo.NoActionBar">
Dica: Se você tem um tema customizado para uma atividade na qual você queira remover a Action Bar, configure o estilo android:windowActionBar para false.

Você também pode esconder a Action Bar em tempo de execução chamando hide(), e mostrá-la novamente chamando show(). Por exemplo:
ActionBar actionBar = getActionBar();
actionBar.hide();
Quando a Action Bar está escondida, o sistema ajusta o conteúdo da atividade para preencher o espaço disponível de tela.

Nota: Se você remover a Action Bar usando um tema, então a janela não permitirá a Action Bar de maneira alguma, então você não poderá adicioná-la em tempo de execução - chamar o método getActionBar retornará null.

Adicionando Itens de Ação



Uma item de ação é simplesmente um item de menu do menu de opções que você declara e que deve aparecer diretamente na Action Bar. Uma item de ação pode incluir um ícone e/ou texto. Se um item de menu não aparece como um item de ação, então o sistema o colocará em um menu flutuante, que o usuário poderá abrir ao tocar o ícone de menu no lado direito da Action Bar.

Quando uma atividade se inicia, o sistema popula a Action Bar e o menu flutuante chamando onCreateOptionsMenu() para sua atividade. 

Você pode especificar um item de menu para aparecer como um item de ação - se existir lugar para ele - a partir de seu recurso de menu declarando, no atributo android:showAsAction="ifRoom" dentro do elemento <item>. Dessa maneira, o item de menu aparece na Action Bar para rápido acesso apenas se existir espaço para ele. Se não há espaço, o item é colocado no menu flutuante, revelado ao clicar no ícone do canto direito da Action Bar.

Você pode também declarar um iem de menu para aparecer como item de ação a partir do seu código fonte, chamando setShowAsAction() no MenuItem e passando a propriedade SHOW_AS_ACTION_IF_ROOM.

Se o seu item de menu tem um título e também um ícone, o item de ação mostrará apenas o ícone. Se você quiser incluir o texto do item de ação, adicione a flag "with text". Basta ir no XML e adicionar withText ao atributo android:showAsAction ou, no seu código, usar a flag SHOW_AS_ACTION_WITH_TEXT quando chamar o setShowAsAction(). 

Abaixo um código de como se declarar um item de menu como um item de ação no arquivo recurso menu.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_add"
          android:icon="@drawable/ic_menu_save"
          android:title="@string/menu_save"
          android:showAsAction="ifRoom|withText" />
</menu>
Nesse caso, ambos o ifRoom e o withText foram setados, para que quando um item apareça como um item de ação, também mostre o texto.

Se você também quiser declarar um item para sempre aparecer como um item de ação, você deverá evitar fazê-lo, pois poderá criar uma interface muito suja com muitas opções de itens de ação colidindo com outros itens na Action Bar.

Usando o ícone do App como um ítem de ação.


Na imagem acima, você vê a Action Bar do Email, com o ícone da aplicação à esquerda.

O comportamento normal deve ser a aplicação retornar para a atividade inicial quando o usuário toca o ícone dele. Quando o usuário toca o ícone, o sistema chama o método onOptionsItemSelected() da atividade com o ID android.R.id.home. Então, você precisa adicionar uma condição para seu método onOptionsItemSelected() escutar o ID que vem de android.R.id.home e efetuar a ação apropriada, como iniciar a atividade home ou abrir algum fragmento.

Se a ação do ícone da aplicação for voltar para a atividade home, você deverá incluir a flag FLAG_ACTIVITY_CLEAR_TOP no seu intent. Com essa flag, se a atividade que você está tentando iniciar já existir na tarefa atual, então todas as atividades dentro desta será destruídas e ela é trazida para a frente. Ou seja, mesmo que você esteja escrevendo um email, ao clicar no ícone da aplicação, ele fechará a janela onde escreve o email e retornará para o ínicio da aplicação. Você deve favorecer esse comportamento, pois ir para a atividade home é uma ação que é equivalente a "voltar para home" e não "criar uma nova home".

O exemplo abaixo mostra uma implementação de onOptionsItemSelected() que retorna para a atividade home:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            // app icon in Action Bar clicked; go home
            Intent intent = new Intent(this, HomeActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
Adicionando uma Action View

Uma action view é um widget que aparece na Action Bar para substituir um item de ação. Por exemplo, se você tem um item no menu de opções para pesquisa, você pode adicionar uma action view para o item que provê um SearchView na Action Bar em qualquer momento que o item estiver disponivel como um item de ação.

Quando declarar um action view como um item de menu, é importante que você ainda permita que o item se comporte como um item de menu normal quando não aparecer no Action Bar. Por exemplo, um item de menu para realizar uma pesquisar deve, por padrão, trazer o diálogo de pesquisa, mas se o item é colocado na Action Bar, a action view aparecer com um widget de SearchView. A figura mostra o exemplo de um widget SearchView em uma Action View.

A melhor maneira de declarar uma action view para um item é dentro do recurso de menu, usando o atributo android:actionLayout ou android:actionViewClass.

O valor para android:actionLayout deve ter o recurso apontando para um arquivo de layout.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_search"
        android:title="Search"
        android:icon="@drawable/ic_menu_search"
        android:showAsAction="ifRoom"
        android:actionLayout="@layout/searchview" />
</menu>
O valor para android:actionViewClass deve ser um nome de classe fully-qualified.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_search"
        android:title="Search"
        android:icon="@drawable/ic_menu_search"
        android:showAsAction="ifRoom"
        android:actionViewClass="android.widget.SearchView" />
</menu>
Você deve incluir a propriedade android:ShowAsAction="ifRoom" para que o item apareça como uma action view quando houver espaço para tal. Se necessário, contudo, você pode forçar o item a aparecer como uma action view mudando a propriedade android:showAsAction para "always".

Agora, quando o item de menu é mostrado como o um action view, sua action view aparece ao invés do ícone e/ou do texto. Contudo, se não há espaço na Action Bar, o item aparecerá dentro do menu flutuante como um item de menu normal e que deve responder à interação do usuário através do método onOptionsItemSelected().

Quando a atividade se inicia, o sistema popula a ActionBar e o menu flutuante chamando onCreateOptionsMenu(). Após você ter inflado o seu menu com esse método, você pode encontrar elementos em uma action view chamando o método findItem() com o ID do item de menu e depois getActionView() no MenuItem retornado. Por exemplo, o widget SearchView pode ser encontrado assim:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.options, menu);
  SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
  // Set appropriate listeners for searchView
  ...
  return super.onCreateOptionsMenu(menu);
}
No próximo post, veremos como adicionar tabs, navegação por drop-down e fazendo a estilização de uma ActionBar. Ah, e claro, não me esqueci do StoryBoard. Só não terminei ainda de desenhar uma versão para mostrar a vocês.



Brasil supera 200 milhões de celulares em 2010

via iG

Li hoje que o Brasil superou a casa dos 200 milhões de celulares em 2010. A notícia boa é que tem mais gente usando aparelhos e, supostamente, haveriam mais consumidores para os apps que vamos criar depois que aprendermos, de fato, a programar para Android.

No entanto, nem tudo é boa notícia. Desses, 82,34% são usuários de serviços pré-pagos. Não quero dizer que quem usa pré-pago não tenha condição de comprar conteúdos. Eu mesmo tenho dois aparelhos, um pós-pago e um pré pago. O meu pós-pago é o meu celular Android. A questão toda é que a penetração de smartphones no Brasil é ainda pequena e, seguramente, a razão é que as pessoas que tem celulares pré-pagos estão preocupados apenas em fazer e receber ligações.

Nesse sentindo, a questão que quero colocar aqui é que devemos pensar em fazer um app que seja, digamos, poliglota. Afinal, o objetivo é abranger um maior número de usuários e não só no Brasil mas em vários países. Então, fazer seu app em inglês, espanhol e francês, além do português, claro, é uma boa medida.

Veremos isso quando chegar a hora.

segunda-feira, 28 de fevereiro de 2011

0 comentários

Interface de Usuários - Criando menus de contexto e submenus

Um menu de contexto é conceitualmente similar ao menu mostrado quando o usuário clica com o botão direito no PC. Você deve usar menus de contexto dar acesso aos usuários às ações pertinentes a um item específico de uma interface de usuário. No Android, o menu de contexto é mostrado quando o usuário pressiona e segura por  um tempo um botão ou item.

Você pode criar um menu de contexto para qualquer View, apesar de menus de contexto serem mais comuns para itens de um a ListView. Quando o usuário pressiona e segura por um tempo um item em uma ListView e a lista está registrada para prover um menu de contexto, o item da lista mostra ao usuário que um menu de contexto está disponível com uma animação em sua cor de fundo - transição do laranja para o branco antes de abrir o menu de contexto).

Para que uma View possa prover um menu de contexto, você deve registrar a view para um menu de contexto. Chame o método registerForContextMenu() e passe o nome da View à qual você quer dar um menu de contexto. Quando essa view receber a ação correta, ele mostrará o menu de contexto.

Para definir a aparência de um menu de contexto e comportamento, faça um override dos métodos de menu onCreateContextMenu e onContextItemSelected.

Por exemplo, aqui está o método onCreateContextMenu() que usa o recurso context_menu.xml:

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
                                ContextMenuInfo menuInfo) {
     super.onCreateContextMenu(menu, v, menuInfo);
     MenuInflater inflater = getMenuInflater();
     inflater.inflate(R.menu.context_menu, menu);
}
O MenuInflater é usado para inflar o menu de contexto de um menu de recurso. Os parâmetros para o método de callback incluem a View que o usuário selecionou e o objeto ContextMenu.ContextMenuInfo que provê informações adicionais sobre o item selecionado. Você deve usar esses parâmetros para determinar qual contexto de menu deverá ser criado, mas nesse exemplo, todos os menus de contexto na atividade são o mesmo.

Então quando o usuário selecionar um item do menu de contexto, o sistema chama o método onContextItemSelected(). Aqui está um exemplo de como você pode processar itens selecionados:

@Override
public boolean onContextItemSelected(MenuItem item) {
  AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
  switch (item.getItemId()) {
  case R.id.edit:
    editNote(info.id);
    return true;
  case R.id.delete:
    deleteNote(info.id);
    return true;
  default:
    return super.onContextItemSelected(item);
  }
}
A estrutura do código acima é similar ao código do post anterior, que faz com que o getItemId() retorne o ID do item de menu selecionado e faz a verificação de qual foi selecionado para performar a ação correta.

Criando Submenus

Um submenu é um menu que o usuário pode abrir selecionando um item em outro menu. Você adicionar um submenu para qualquer menu (exceto um submenu). Submenus são úteis quando sua aplicação tem muitas funções que você precisa organizar em tópicos, como itens de um PC (Arquivo, Editar, Ver, etc).

Quando criar um recurso de menu, você pode criar um submenu adicionando um elemento <menu> como filho de um item <item>. Por exemplo:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/file"
          android:icon="@drawable/file"
          android:title="@string/file" >
        <!-- "file" submenu -->
        <menu>
            <item android:id="@+id/create_new"
                  android:title="@string/create_new" />
            <item android:id="@+id/open"
                  android:title="@string/open" />
        </menu>
    </item>
</menu>
Quando o usuário seleciona um item de um submenu, o menu pai faz a seleção do método callback que recebe o evento.

Interface de Usuários - Criando menus

Menus são uma parte importante da interface de usuário em uma atividade que dão aos usuários uma forma familiar de executar tarefas. O Android oferece um framework simples para você adicionar menus padrão para sua aplicação.

Existem três tipos de menus:
  • Menus de opção - Coleção primária de itens de menu para uma atividade, que aparecem quando o usuário toca o botão MENU. Quando sua aplicação está rodando em Android 3.0 ou superior, você pode prover um rápido acesso aos itens de menu inserindo-os diretamente na Action bar, como action items.
  • Menus de contexto - Uma lista de itens flutuantes que aparecem quando o usuário toca ou segura uma view que está registrada para mostrar menus de contexto.
  • Submenu - Uma lista de itens de menu que aparecem quando o usuário toca um item de menu que contém um menu aninhado.
Criando um recurso Menu

Ao invés de instanciar o Menu em seu código de aplicação, você deverá definir um menu e todos os seus itens em um arquivo XML de recurso de menu (carregue-o como um objeto programável) em seu código de aplicação. Usando um recurso de menu para definir seu menu é uma boa prática porque separa o conteúdo do menu de seu código de aplicação. É mais fácil visualizar a estrutura e conteúdo de um menu em um XML.

Para criar um recurso de menu, crie um arquivo XML dentro da pasta res/menu/ e crie o menu com os seguintes elementos:

<menu>
Define o menu, que é um container de itens de menu. Um elemento <menu> deve ser o nó raiz do arquivo e pode guardar um ou mais elementos do tipo <item> e <group>.

<item>
Cria um item de menu. Esse elemento pode conter um menu aninhado de maneira a criar um submenu.

<group>
Um conteiner opcional para contem elementos do tipo <item>. Permite categorizar os itens de menu para que eles guardem propriedades como estado de atividade e visibilidade.

Abaixo um exemplo de um menu chamado game_menu.xml
<?xml version="1.0" encoding="utf-8"?>
   <menu xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:id="@+id/new_game"
         android:icon="@drawable/ic_new_game"
         android:title="@string/new_game" />
      <item android:id="@+id/help"
         android:icon="@drawable/ic_help"
         android:title="@string/help" />
</menu>

Esse exemplo define um menu com dois itens. Cada item inclui os seguintes parâmetros:

android:id
O ID do recurso que deve ser único, que permite a aplicação reconhê-lo quando o usuário o seleciona.

android:icon
Uma referência a uma imagem (drawable) para ser usado como icone do item.

android:title
Uma referência para uma string a ser usada como título do item.

Inflando o recurso de menu

De seu código de aplicação, você pode inflar um recurso de menu (que é converter um recurso XML em um objeto programável) usando MenuInflater.inflate(). Por exemplo, o código seguinte infla o game_menu.xml durante o método de callback onCreateOptionsMenu() para usá-lo como menu de sua atividade.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.game_menu, menu);
      return true;
}
O método getMenuInflater() retorna um MenuInflater para a atividade. Com esse objet, você pode chamar o método inflate(), que infla o recurso menu em um objeto menu. Nesse exemplo, o recurso de menu definido por game_menu.xml inflado para o Menu que é passado em onCreateOptionsMenu().

Criando um menu de opções

O menu de opções é onde você deverá incluir ações básicas e itens de navegação básicos (por exemplo, um botão para abrir as configurações da aplicação). Itens no menu de opções são acessíveis de duas maneiras distintas: o botão MENU ou na Action Bar (em dispositivos rodando Android 3.0 ou superior).



Quando rodando em dispositivos anteriores à versão 3.0, o menu de opções aparece no rodapé da tela, como mostrada na figura abaixo. Quando aberta, a primeira parte visível do menu de opções é o menu de ícones. Ele guarda os primeiros seis itens de menu. Se você adicionar mais que seis itens a esse menu, o Android vai substituir o sexto item por um que possa abrir um menu flutuante.

No Android 3.0 e superior, itens do menu de opções são inseridos na Action Bar, que aparece no topo da atividade em lugar da barra de título tradicional. Por padrão todos os itens de um menu de opções são colocados em um menu flutuante, que o usuário pode abrir bastando tocar o ícone. Contudo, você pode inserir alguns itens de menu diretamente na Action Bar como items de ação (action items), para acesso instantâneo, como mostrado na imagem abaixo.



Respondendo a ação do usuário

Quando um usuário seleciona um item do menu de opções (incluindo itens de ação da Action Bar), o sistema chama pelo método de atividade onOptionsItemSelected(). Esse método passa o item de menu (menuItem) que o usuário selecionou. Você pode identificar o item chamando getItemId(), que retorna o ID único para o item de menu (definido em android:id). Você pode selecionar uma ação especifica dependendo do item selecionado. Por exemplo:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
  // Captura o menu selecionado
   switch (item.getItemId()) {
      case R.id.new_game:
         newGame();
         return true;
      case R.id.help:
         showHelp();
         return true;
      default:
         return super.onOptionsItemSelected(item);
   }
}
Nesse exemplo, getItemId() chama o ID do item de menu seleciona e faz um switch para comparar o ID aos recursos assinalados aos itens de menu no recurso XML. Quando um switch case tem sucesso em processar o item de menu, ele retorna true para indicar que a seleção do item foi processada. Caso contrário, a cláusula default passa o item de menu para a super classe, no caso dele conseguir processar o item selecionado.

Adicionalmente, o Android 3.0 adiciona a possibilidade de você definir um comportamento para o onClick no recurso XML, usando o atributo android:onClick. Assim, você não precisará implementar onOptionsItemSelected(). Usando o android:onClick, você pode especificar o método a ser chamado quando o usuário seleciona o item de menu. Sua atividade deve implementar o método especificado no android:onClick para que ele aceite um parâmetro único - que é o item de menu selecionado que é passado pelo sistema para o método.

Dica: Se sua aplicação contém múltiplas atividades e algumas delas provêem o mesmo menu de opções (recurso compartilhado, por exemplo), considere criar uma atividade que implementa nada exceto o onCreateOptionsMenu() e onOptionsItemSelected(). Então extenda essa classe para cada atividade que você deverá compartilhar com o mesmo menu de opções. Dessa maneira, você poderá gerenciar apenas um pacote de códigos para manusear o menu de opções e cada classe descendente que herde seu comportamento de menu. 
Se você quer adicionar um item de menu para ua de suas atividades descendentes, faça o override em onCreateOptionsMenu() nessa atividade. Chame super.onCreateOptionsMenu(menu) para que o os items de menu originais sejam criados e então adicione os novos itens de menu usando menu.add().

Mudando itens de menu em tempo de execução

Uma vez que a atividade é criada, o método onCreateOptionsMenu() é chamado apenas uma vez. O sistema mantém e reusa o menu definido nesse método até que a atividade seja destruída. Se você quer mudar o menu de opções em qualquer momento após sua criação, você deve fazer o override do método onPrepareOptionsMenu(). Esse método passa a você o objeto menu em sua existência atual, com todos os itens populados. Assim, você pode remover, adicionar, desabilitar ou habilitar itens de menu dependendo do estado atual de sua aplicação.

Em versões do Android anteriores à 3.0, o sistema chama onPrepareOptionsMenu() a cada vez que o usuário abre o menu de opções.

Em Android 3.0 e superior, você deve chamar o método invalidateOptionsMenu() quando você quer fazer uma atualização do menu, pois o menu está sempre aberto. O sistema vai chamar o método onPrepareOptionsMenu() para que você possa fazer as atualizações necessárias.

Nota: Você nunca deverá mudar os itens de um menu de opções baseado na view que está em foco. Quando está em modo de touchscreen, as visões não conseguem manter o foco, então você NUNCA deverá usar o foco como a base para modificar itens em seu menu de opções. Se você quer prover itens de menu que são sensíveis ao contexto para serem usadas em uma view, use um menu de contexto, que será o próximo item a ser comentado por aqui, juntamente com os submenus.

domingo, 27 de fevereiro de 2011

0 comentários

Ativações de Smartphones Android entre Outubro-2008 e Janeiro-2011

E ai, ainda não se convenceu a começar a programar para o Android? Veja o vídeo abaixo e se convença!



E pense bem! O mais impressionante é que, depois do lançamento do Droid, a quantidade de ativações foi lá para cima! Para quem não sabe, o Droid é o nosso Milestone. E depois do Samsung Galaxy S? Impressionante MESMO!

Mas, pode onde começar?
  1. O que é o Android?
  2. Por onde começar a programar?
  3. Livros de Android.
  4. Como esse blog vai me ajudar a programar para Android?
Meu convite continua aberto: Eu mesmo estou iniciando nesse caminho. Já sou programador há anos e agora vejo nesse nicho uma oportunidade de ouro para novos horizontes. E então, quer caminhar comigo?

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Related Posts Plugin for WordPress, Blogger...