quinta-feira, 20 de outubro de 2011

Android: Dicas 5

Olá povo,

Esse é mais um post da série de dicas de Android. Aproveitem e deixem seus comentários :)

Dica 1 - Alterando a fonte dos componentes
O Android, por padrão, tem apenas 3 fontes que podem ser utilizadas nos componentes visuais: sans, serif e monospace. Para utilizar cada uma delas, basta atribuir o valor desejado à propriedade android:typeface. Mas se quiser utilizar uma nova fonte, basta adicionar o arquivo *.ttf na pasta assets e carregá-la utilizando o código abaixo.
Typeface typeface =
Typeface.createFromAsset(getAssets(), "Aliens.ttf");

TextView txt = (TextView)findViewById(R.id.textView1);
txt.setTypeface(typeface);

Infelizmente, não achei uma forma de setar essa fonte no XML. Se alguém souber, deixe um comentário. Ah! A fonte que usei nesse exemplo foi baixada do site http://www.webpagepublicity.com/free-fonts.html.

Dica 2 - Converter DIP (Density Independent Pixel) para Pixel
Após ministrar duas aulas seguidas (em turmas diferentes) sobre Views personalizadas no Android, uma dúvida frequente foi como converter DIP para PX (pixel). Isso é especialmente útil para que a View rode corretamente em diferentes densidades de tela (LDPI, MDPI, HDPI e agora XHDPI). Para tal, pode-se utilizar o método applyDimension da classe TypeValue.
Resources r = getResources();
float valorEmDp = 14;
float valorEmPixels = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, valorEmDp,
r.getDisplayMetrics());


Dica 3 - Evitando acumular Toasts
Um "bug" clássico que os engenheiros de teste do projeto em que eu trabalho levantam é sobre a utilização do Toast. Se você chamar o método show() dessa classe várias vezes seguidas, essas mensagens são acumuladas e ficam sendo exibidas sequencialmente. Um recurso que utilizo é criar um método separado, que verificará se já existe um Toast aberto, em caso positivo, ele o cancela para exibir um novo. Para tal, você deve criar um atributo da classe Toast (que abaixo chamo de 'toast') e utilizar o seguinte código:
// Declare o atributo
private static Toast toast;

// Método
public static void showToast(Context ctx, int res){
if (toast != null){
toast.cancel();
toast.setText(res);
} else {
toast = Toast.makeText(ctx, res, Toast.LENGTH_LONG);
}
toast.show();
}


Dica 4 - Definindo onde instalar sua aplicação
A partir da versão 2.2 (Froyo) é possível especificar onde sua aplicação pode ser instalada: cartão de memória ou memória interna. Por padrão, a aplicação será instalada na memória interna, mas você pode utilizar a propriedade android:installLocation da tag <manifest> do AndroidManifest.xml para um dos valores abaixo:
internalOnly - A aplicação só poderá ser instalada na memória interna (valor padrão).
auto - A aplicação é instalada na memória interna, mas poderá ser movida para o cartão de memória posteriormente ou quando a memória interna estiver cheia.
preferExternal - A aplicação deve ser instalada no cartão de memória preferencialmente, mas isso não é garantido.

Exemplo:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="preferExternal"
... >


Dica 5: Ativar/Acender a tela do aparelho
Neste post eu mostrei como criar notificações no Android. Um recurso que pode ser utilizado juntamente com as notificações é acender/ligar a tela do aparelho. Para fazer isso, deve-se utilizar a classe PowerManager.

// Obtém a instância do PowerManager
PowerManager pm = (PowerManager)c.getSystemService(
Context.POWER_SERVICE);

// Liga o display do aparelho
WakeLock wakeLock = pm.newWakeLock(
// Liga a tela
PowerManager.SCREEN_DIM_WAKE_LOCK |
// Após liberar a tela para apagar,
// mantém a tela ligada por um pouco
// mais de tempo
PowerManager.ON_AFTER_RELEASE,
// Tag para debug
"tag_para_debug");

// Liga a tela por 10 segundos
wakeLock.acquire(10000);


Para usar o código acima, deve-se adicionar a permissão WAKE_LOCK no AndroidManifest.xml.
<uses-permission name="android.permission.WAKE_LOCK"/>


Dica 6: debug.keystore expirou

Essa dica foi enviada pelo meu colega Ricardo Gilson.
Toda aplicação Android é assinada para ser instalada no dispositivo, por padrão, ela é assinada com uma assinatura de debug através do arquivo debug.keystore que fica na subpasta ".android" no diretório do usuário (C:\Users\usuario\.android ou /Users/usuario/.android). Depois de um certo tempo sem utilizar a máquina, a mensagem abaixo pode ser exibida ao tentar rodar uma aplicação:

Error generating final archive: Debug Certificate expired on 24/09/2011.

Para resolver o problema é só apagar o arquivo debug.keystore, dar um clean no projeto do Eclipse (menu Project > Clean) e tentar rodar novamente.

Dica 7: Habilite a aceleração de Hardware (por Fernado Fragoso)
Habilitar a aceleração de hardware quando necessitar de manipulação de imagens, adicionar na tag application do AndroidManifest.xml.

android:hardwareAccelerated="true"

Faz uma diferença gigantesca! Valeu Fernando!

Por hoje é só, qualquer dúvida ou sugestão, deixem seus comentários.

4br4ç05,
nglauber

13 comentários:

Diego disse...

Cara, show de bola seu blog .... descobri ele hoje, acabei de adicionar os RSS :)


Parabens e sucesso !

Unknown disse...

Glauber, no dica três do TOAST, o parâmetro do método showToast não deveria ser uma STRING ao invés de um int?

Abraço

Nelson Glauber disse...

Oi Diego,

Valeu pelo elogio!

Oi Felipe,

Usei um int pois parti do presuposto que devemos deixar as strings no values/strings.xml, logo devemos passar uma referência para R.string.minha_string

4br4ç05,
nglauber

Gui de Guinetik disse...

óa, só uma coisinha:
android:hardwareAccelerated
só rola do 3.0 pra cima :(

Anônimo disse...

Qual valor e passo como parametro no Context?

Nelson Glauber disse...

Oi Anônimo,

A classe Activity herda de Context. Então, se você está chamando esse método de uma Activity, basta passar this.

4br4ç05,
nglauber

Anônimo disse...

Dica 3 - Evitando acumular Toasts

Como poderia fazer seguindo esse exemplo para adicionar uma imagem e o texto no Toast?

Nelson Glauber disse...

Oi Anônimo,

A classe Toast tem um método setView onde você pode definir a View que você quiser. Inclusive pode ser um layout completo, afinal de contas, um arquivo de layout é transformado em um objeto View. Por exemplo:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

ImageView img = new ImageView(this);
img.setImageResource(R.drawable.ic_launcher);

TextView txt = new TextView(this);
txt.setText("Toast personalizado");

ll.addView(img);
ll.addView(txt);

Toast t = new Toast(this);
t.setView(ll);
t.show();

4br4ç05,
nglauber

Anônimo disse...

I do not even know how I ended up here, but I thought this post was great.

I do not know who you are but certainly you're going to a famous blogger if you aren't already ;) Cheers!
Check out my web-site : causes of foot and ankle swelling

Nelson Glauber disse...

Hi Anonymous,

Thanks for your comment. Words like these is to encourage me to continue with the blog.

[]'s
nglauber

César Oliveira disse...

Dicas muito uteis, parabéns

Ainda há dias um colaborador me perguntava como fazer com que a aplicação seja armazenada no cartão SD e eu disse-lhe que ia pesquisar sobre isso. E agora a resposta surgiu no seu blog.

Você está a fazer um excelente trabalho relativo ao Android e em Português. Parabéns mais uma vez.

Anônimo disse...

Olá boa noite,

Estou lendo seu livro: Dominando o Android e no exercício 7: Ex07_TextView, quando utilizo:
Typeface typefaceLight = Typeface.createFromAsset(getAssets(),"Roboto-Light.ttf");
O app para.
Criei a pasta assets, copiei as fontes para lá, mas não consigo resolver este problema. O aplicativo sempre para neste ponto.

Nelson Glauber disse...

Oi Anônimo,

Posta essa dúvida lá no grupo!
https://groups.google.com/forum/#!forum/livro-dominando-o-android
Mas sem o log, fica dífícil ajudar...

Checa se a pasta assets está dentro de src/main e se o nome do arquivo está correto (diferenciando maiúsculas e minúsculas).

4br4ç05,
nglauber