quinta-feira, 2 de dezembro de 2010

Android: Dicas de programação da semana

Olá povo,

No novo projeto em que estou envolvido estamos desenvolvendo várias aplicações. Como temos várias pessoas envolvidas, algumas dúvidas se tornam recorrentes, então resolvi postá-las.

Pergunta 1: Quando eu giro o telefone o método onCreate da Activity é chamado novamente. Tem como evitar isso?

Resposta: Sim, basta adicionar a propriedade android:configChanges na tag <activity> do seu AndroidManifest.xml. Isso evitará que a atividade seja recriada.

<activity android:name="MinhaActivity"
android:configChanges="keyboardHidden|orientation"/>

No caso acima, se o telefone mudar de orientação ou se o teclado físico (se houver) for aberto, a atividade não será recriada.

Pergunta 2: Tem como deixar uma atividade apenas em landscape ou portrait?

Resposta: Sim, basta utilizar a propriedade android:screenOrientation na tag <activity> do seu AndroidManifest.xml.

<activity name=".MinhaActivity"
android:screenOrientation="landscape"/>


Pergunta 3: Como permitir apenas letras na caixa de texto (EditText)?

Resposta: Não existe uma propriedade para fazer isso. Se quisermos colocar para aceitar apenas números podemos utilizar a propriedade android:inputType="number". Ou quando queremos deixar todas as letras em maiúsculo podemos usar o valor textCapCharacters. Mas para não aceitar nem números nem símbolos só com a boa e velha expressão regular.

Pattern pattern = Pattern.compile(
"^[A-ZÁÀÄÃÂÆÅÉÈËÊÍÌÏÎÓÒÖÕÔØŒÚÙÜÛÝÿYÑÇ ]+$");

Matcher matcher = pattern.matcher(
meuEditText.getText().toString().toUpperCase());

if (!matcher.matches()){
Log.e("ERRO",
"Esse campo só aceita letras e espaço em branco!");
}


Pergunta 4: Como fazer uma lista múltipla que eu possa selecionar vários itens?

Resposta: Devo confessar que esse problema me encheu muito o saco. Não para criar a lista, mas sim para obter os itens selecionados. Pra informar que sua ListView permite seleção múltipla use o método setChoiceMode(int).

lstView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

Feito isso, sua lista já permitirá seleção múltipla. Agora como fazer para obter os itens selecionados? Bem, a classe ListView tem dois métodos que você pode obter arrays com as posições e os ids dos itens selecionados: getCheckItemPositions() e getCheckItemIds(). Infelizmente não tive uma boa experiência com eles. Ao marcar e desmarcar itens, aconteciam momentos em que os itens ficavam inconsistentes, ou seja, ele informava que itens estavam marcados, quando na verdade não estavam. Sendo assim, preferi fazer da minha forma:

private int getCheckedCount(){
lstView.getCheckItemIds();

int count = 0;
int listSize = lstView.getAdapter().getCount();
for (int i = 0; i < listSize; i++) {
if (lstView.isItemChecked(i)){
count++;
}
}
return count;
}

// Para marcar ou desmarcar um item específico,
// podemos usar:
lstView.setItemChecked(posicao, false);


Pergunta 5. Como carregar uma imagem da aplicação baseada no nome do arquivo?

Resposta: Se esse recurso estiver na pasta res/drawable você pode fazer via reflection. Eu já fiz um post sobre isso, que vocês podem conferir aqui. Mas se quiser usar de maneira descente :) podem usar a pasta assets do seu projeto. Coloque as imagens que você deseja carregar dinamicamente nesse diretório e faça como abaixo:

try {
InputStream is = getAssets().open("imagem.png");
Bitmap bmp = BitmapFactory.decodeStream(is);
ImageView img = (ImageView)
findViewById(R.id.ImageView01);

img.setImageBitmap(bmp);

} catch (IOException e) {
e.printStackTrace();
}


Pergunta 6. Como salvar uma informação simples como o recorde do jogo?

Resposta: Para persistir informações simples, o Android disponibiliza a classe SharedPreferences onde você pode salvar pequenas configurações. Vejam abaixo como ler/escrever uma preferência através de dois métodos de exemplo que salvam e recuperam o recorde de pontos de um jogo.

public int getRecord(){
SharedPreferences prefs =
context.getSharedPreferences(
"configs", Context.MODE_PRIVATE);

return prefs.getInt("record", 0);
}

public void setRecord(int record){
SharedPreferences prefs =
context.getSharedPreferences(
"configs", Context.MODE_PRIVATE);

SharedPreferences.Editor editor = prefs.edit();
editor.putInt("record", record);
editor.commit();
}


Pergunta 7. Como ler um XML do diretório res/xml?

Resposta: Quem é meu aluno já conhece essa frase que eu uso sempre nas aulas: Existem mil maneiras de se fazer Neston :) Uma das maneiras de ler um XML é usando o XMLResourceParser, segue um exemplo bem simples do seu uso. Clique aqui pra ver o post original.


private String getEventsFromAnXML(Context c)
throws XmlPullParserException, IOException {

StringBuffer stringBuffer = new StringBuffer();
Resources res = c.getResources();
XmlResourceParser xpp = res.getXml(R.xml.meu_xml);
xpp.next();

int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT){
if(eventType == XmlPullParser.START_DOCUMENT) {
stringBuffer.append("--- Start XML ---");

} else if(eventType == XmlPullParser.START_TAG){
stringBuffer.append("\nSTART_TAG: "+
xpp.getName());

} else if(eventType == XmlPullParser.END_TAG){
stringBuffer.append("\nEND_TAG: "+
xpp.getName());

} else if(eventType == XmlPullParser.TEXT) {
stringBuffer.append("\nTEXT: "+xpp.getText());
}
eventType = xpp.next();
}
stringBuffer.append("\n--- End XML ---");
return stringBuffer.toString();
}

De acordo com a evolução do projeto vou colocando mais dicas.

4br4ç05,
nglauber

4 comentários:

Unknown disse...

Parabéns Pelo Blog. Uma ótima referência em língua portugues!

Cristian Chies disse...

Parabéns, issas dicas me salvaram 2 vzs já!!!...ehehhe...
Grande abraço....

Ademar Oliveira disse...

Perfeito e claro ;D

valeu meu caro!!!

César Oliveira disse...

Dicas fabulosas, parabéns.
Para além de serem muito bem explicadas.
Você é mesmo um excelente professor.

Parabéns