Dev (Back & Front)ARTIGO

Desenvolvimento para Android usando widgets Eclipse e Android – Parte 02

Na primeira parte deste artigo iniciamos o
desenvolvimento para Android em
Eclipse usando os plug-ins de ferramentas de desenvolvimento para
Android, além de oferecer insights sobre os recursos notáveis de um aplicativo
Android, juntamente com uma breve explicação de seus componentes
básicos.

Acompanhe agora como o processo do
Android é introduzido para o desenvolvimento de UIs ricas para
os aplicativos, como widgets. Ao final, ainda dá é possível mostra como é fácil testar o aplicativo de desenvolvimento
implementando-o no simulador de dispositivo Android, incluído no SDK.

Widgets do Android

Agora que sabemos como criar e executar um aplicativo Android básico, vamos adicionar widgets nele (consulte a Figura 7):

01.  textView consiste em widgets como editText, Button, etc. Botões podem ainda ser categorizados em:

  • CheckBox
  • RadioButton
  • ToggleButton etc.

02.  ImageView consiste em widgets como o ImageButton.

03.  ViewGroup consiste em layouts como:

  • Relative Layout
  • Table Layout
  • Frame Layout
  • Adapter View
  • Linear Layout

Para obter informações sobre widgets, A Visual Guide to Android GUI Widgets
é o melhor guia. No entanto, tenha cuidado com inconsistências
introduzidas nele por causa das rápidas mudanças na plataforma Android.

Um exemplo evidente é o uso de id como um atributo Identificador para um widget em main.xml no guia mencionado acima. Na plataforma Android mais recente, o android:id totalmente qualificado deverá ser usado.

Figura 7. Hierarquia dos widgets Android

Uma amostra de aplicativo usando widgets

Agora, modificaremos nosso aplicativo existente para que fique
parecido com o mostrado na Figura 8. A finalidade deste exemplo é
familiarizar o leitor com o uso de alguns widgets básicos, como textView, editText, Button e Toast em um aplicativo real.

Nosso aplicativo consistirá em uma barra de título com a mensagem “WELCOME!!!”
Ele terá três widgets textView iniciados a partir da parte
superior, dispostos verticalmente: um dizendo “Hello World, how’re you?”
na fonte padrão. O próximo dizendo “Welcome to my first Android app” em
texto serif itálico, alinhado ao centro, com fundo branco e um terceiro
dizendo “Type anything
and press the button” em texto com espaço simples em
negrito, com fundo vermelho.

Esses três são seguidos por um widget
editText para obter a entrada do usuário, seguido por um widget
de botão (o botão tem a mensagem “Click Me!”).
O que for digitado no widget editText aparecerá em um widget Toast na parte inferior central da tela quando o botão for pressionado.

Não há muitos códigos de implementação envolvidos. O
leitor deverá prestar atenção em como os
widgets são facilmente inseridos no aplicativo usando o editor da GUI do
ADT para os arquivos
XML e como as propriedades do widget são convenientemente definidas
usando a visualização
“properties” fornecida pelo Eclipse. Este exemplo também demonstrará
como a UI e as partes de implementação podem ser codificadas de forma
independente.

Figura 8. Android Virtual Device com widgets

string.xml

Vamos adicionar novas cadeias de caracteres no arquivo string.xml,
alterar a cadeia de caracteres de boas-vindas existente e, finalmente, a
cadeia de caracteres do título. Vamos também definir aqui as cores
branco e vermelho para o fundo para dois textViews.

Listagem 2. O arquivo string.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, how're you?</string>
<string name="app_name">Hello Android</string>
<string name="title">WELCOME!!!</string>
<string name="mainText">Welcome to my first android app</string>
<string name="subText">Type anything and press the button</string>
<color name="White">#FFFFFF</color>
<color name="Red">#FF0000</color>
</resources>

Alteramos a cadeia de caracteres “hello” para conter “Hello World, how’re you?” Note que o caractere de escape
(”) é necessário aqui para o apóstrofo. Também definimos duas novas cadeias de caracteres: mainText e subText, e as cores branco e vermelho.

main.xml

Vamos usar a guia Layout de main.xml para arrastar e soltar dois novos
textViews: um widget editText e um widget de botão. A seguir, usaremos a guia properties no main.xml para editar atributos para cada widget.

Listagem 3. O arquivo main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
<TextView
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:id="@+id/mainTextView"
    android:gravity="center"
    android:text="@string/mainText"
    android:textStyle="italic"
    android:typeface="serif"
    android:background="@color/White">
</TextView>
<TextView
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_margin="20sp"
    android:gravity="left"
    android:id="@+id/subTextView"
    android:padding="10sp"
    android:text="@string/subText"
    android:textStyle="bold"
    android:typeface="monospace"
    android:background="@color/Red">
</TextView>
<EditText
    android:text="Enter text here"
    android:id="@+id/EditText01"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
</EditText>
<Button
    android:text="Click me!"
    android:id="@+id/Button01"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
</Button>
</LinearLayout>

Com isto, temos nossa UI definida. Agora temos que vincular nosso código de atividade a ela.

MainActivity.java

Este é o arquivo que vincula de fato a UI à implementação. Assim como no aplicativo
HelloWorld, usamos o método Activity.onCreate(Bundle) para decorar todos os elementos da UI na tela. O método onClick(View) substituído conterá a funcionalidade do clique do botão, em que o texto
de entrada do usuário será lido e exibido na tela em um widget toast.

Listagem 4. O arquivo MainActivity.java

package com.example.helloandroid;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        String title = getString(R.string.title);
        setTitle(title);    // done so that we can change the default title
        
        //get handles to editText and button widgets
        final EditText eText = (EditText) findViewById(R.id.EditText01);
        final Button button = (Button) findViewById(R.id.Button01);
        
        button.setOnClickListener(new Button.OnClickListener(){

            @Override
            public void onClick(View v) {
                //get the String entered into the editText widget
                CharSequence editText = eText.getText();
                
                //display the toast
                Toast.makeText(MainActivity.this, editText, Toast.LENGTH_LONG).show();
            }
        });
        
    }
}

Usando este código, obtemos o aplicativo mostrado na Figura 8.

Usando o widget: Um aplicativo de amostra

Nesta seção, criaremos um aplicativo de amostra (consulte as Figuras
9a, 9b) para exibir todos os contatos na Lista de contatos usando o
widget listView. O objetivo deste exemplo é demonstrar não só o uso do widget listView, mas também mostrar como os dados do telefone podem ser recuperados
usando as classes ContentProvider e ContentResolver.

Preste atenção nos
arquivos XML da UI, pois existem dois layouts de UI: um para especificar
como a lista exibida pelo widget listView se encaixa na UI
principal e outro para especificar como cada elemento da lista se
parece.

Outro ponto importante é a configuração das permissões para que o
aplicativo seja capaz de ler os dados do telefone. Este exemplo é a
primeira etapa para entender como intentos e filtros de intentos podem
ser incorporados em um aplicativo.

Apesar de intentos estarem fora do
escopo deste artigo, o leitor poderá notar que para converter este
aplicativo de exemplo em um aplicativo de Lista de contatos real, basta
implementar ações de clicar nos itens da lista e criar um intento de
chamada e filtro de intentos para iniciar uma chamada para o contato
selecionado.

Neste exemplo, os contatos serão exibidos de forma linear
na vertical e o contato selecionado aparecerá no topo da lista com uma
fonte grande em itálico e um fundo azul. Também temos uma caixa de
opções na parte inferior esquerda da tela que, ao ser marcada, exibe
somente contatos com estrelas (ou favoritos). O título do aplicativo,
neste caso, é “Contact Manager.”

Aqui, usamos três tipos de widgets: textView, listView e checkBox. Usamos o widget textView para exibir o contato selecionado. É possível presumir que o widget listView
seja uma lista de widgets textView. Um listView usa padrões de design de adaptadores para conectar os dados (neste caso, os contatos) e uma visualização de dados (um textView, neste caso) para listView. Quaisquer cliques em listView podem ser capturados implementando AdapterView.OnItemClickListener().

Antes de continuar, devemos ter alguns contatos armazenados na seção Contacts do emulador do Android
(AVD). Isto pode ser feito ao clicar em Contacts
na tela principal do AVD e, a seguir, em Menu para obter a opção
Add Contacts. A seção
Favorites mostra como marcar um contato como favorito/com estrela.

Figura 9a. O aplicativo Contacts mostrando todos os contatos em um widget listView

Figura 9b. O aplicativo Contacts mostrando todos os contatos com estrelas em um widget listView quando a caixa de opção show-starred contacts estiver selecionada

Agora, definiremos algumas cadeias de caracteres.

Listagem 5. Cadeias de caracteres definidas no arquivo strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="hello">Hello World, Manager!</string>
  <string name="app_name">Contact Manager</string>
  <string name="selectedEntry" />
  <color name="White">#FFFFFF</color>
  <color name="Black">#000000</color>
  <color name="Blue">#0000FF</color>
 <string name="showStarred">Show starred contacts only</string>
</resources>

main.xml

Vamos definir o layout principal para nosso aplicativo. O widget listView acomodará a lista de todos os contatos na lista de contatos. O listView exibe cada item dentro de um widget textView, que definiremos a seguir.

Listagem 6. main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:id="@+id/selectedContact"
    android:padding="10dp"
    android:textSize="20sp"
    android:textStyle="italic"
    android:typeface="serif"
    android:background="@color/Blue"
    android:textColor="@color/White"
    android:text="@string/selectedEntry"/>
<ListView
    android:id="@+id/contactsListView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1">
    </ListView>
<CheckBox android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/showStarred"
    android:text="@string/showStarred"/>
</LinearLayout>

Note que atribuir um layout_weight de 1 a listView assegura que a lista abrangerá o máximo possível da tela principal até que um novo widget seja definido.

contactItem.xml

Além do layout principal, precisamos definir aqui outro layout. Ele servirá para representar cada elemento no listView. Usamos um textView simples aqui.

Listagem 7. Código para o widget textView , que constitui cada elemento do widget listView

<?xml version="1.0" encoding="utf-8"?>
<TextView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:padding="5dp"
  android:textStyle="bold"
  android:id="@+id/contactItem">
</TextView>

Note que, por padrão, o Android fornece um layout simples que pode ser
usado, em vez de definir o seu próprio layout. Ele pode ser referenciado
por meio do android.R.layout.simple_list_item_1.

ManageContacts.java

A Listagem 8 mostra como a atividade principal é implementada. O método populateContactList() é o que usaremos para consultar o banco de dados de contatos e exibi-los no listView.

Listagem 8. Implementação da atividade principal

public class ManageContacts extends Activity {
    private ListView mContactList;
    private CheckBox mCheckBox;
    private boolean mShowStarred;
    private TextView selectedText;
     /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mContactList = (ListView) findViewById(R.id.contactsListView);
        mCheckBox = (CheckBox) findViewById(R.id.showStarred);
        selectedText = (TextView) findViewById(R.id.selectedContact);
        mShowStarred = false;
        
        mCheckBox.setOnCheckedChangeListener(new CheckChangedListener());
        
        mContactList.setOnItemClickListener(new ClickListener());
        
        populateContactList();
       
    }
    
    public void populateContactList() {
         Uri uri = ContactsContract.Contacts.CONTENT_URI;
         String[] projection = new String[] {
                 ContactsContract.Contacts._ID,
                 ContactsContract.Contacts.DISPLAY_NAME,
         };
         String[] selectionArgs = null;
         String sortOrder = ContactsContract.Contacts.DISPLAY_NAME +
" COLLATE LOCALIZED ASC";
         String selection = mShowStarred? ContactsContract.Contacts.STARRED +
" ='1'" : null;
         Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs,
sortOrder);
         
         String[] fields = new String[] {
                 ContactsContract.Data.DISPLAY_NAME
         };
         SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.contactitem,
c, fields, new int[] {R.id.contactItem});
         mContactList.setAdapter(adapter);
         
    }
    
    private class ClickListener implements OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> arg0, View textView, int pos, long arg3) {
            if(textView instanceof TextView)
                selectedText.setText(((TextView) textView).getText());
         }
     }
    
    private class CheckChangedListener implements OnCheckedChangeListener {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
             mShowStarred = isChecked;
             selectedText.setText("");
             populateContactList();
            
        }
        
    }
}

O que deve ser observado:

  • Temos dois listeners – um para manipular cliques em
    um item da lista e um para manipular cliques na caixa de opção. O
    primeiro simplesmente define o texto na caixa textView azul para exibir o nome do contato selecionado. O segundo define o campo mShowStarred e preenche a lista novamente.

  • Para ler os contatos do banco de dados do telefone,
    precisamos consultá-lo para obter um cursor. A consulta tem os seguintes
    parâmetros:

  1. uri: O URI usando o esquema content:// para o conteúdo a ser recuperado.
  2. projection: Uma lista de quais colunas deverão ser retornadas.
    Passar null retornará todas as colunas, o que não é recomendado para
    evitar a leitura de dados de um armazenamento que não será usado. 
  3. selection: Um filtro assegurando quais linhas deverão ser retornadas, formatado como uma cláusula
    SQL WHERE (excluindo o WHERE em si). Passar null retornará todas as linhas para o URI dado. 
  4. selectionArgs: É possível incluir ?s, que serão substituídos pelos valores de
    selectionArgs, na ordem em que aparecem na seleção. Os valores serão vinculados como Strings. 
  5. sortOrder: Como ordenar as linhas, formatadas como uma cláusula SQL ORDER BY
    (excluindo o ORDER BY em si). Passar null usará a ordem de classificação padrão, que poderá ser não ordenada.

O cursor do conjunto de resultados obtido desta forma deve ser vinculado à UI por meio de um adaptador. Usamos um SimpleCursorAdapter aqui, apesar de o Android também fornecer um ListAdapter.
Quando o adaptador for obtido, precisaremos conectá-lo ao listView e teremos concluído.

Permissões

Uma etapa final necessária antes que nosso aplicativo seja executado
com sucesso em um dispositivo Android é a definição de permissões. Sem
permissões que possibilitem a leitura do banco de dados de contatos, o
kernel Linux no dispositivo não permitirá que a aplicação o faça.

Portanto, vamos acessar a guia AndroidManifest.xml>Permissions
e definir as seguintes permissões:

  1. android.permission.GET_ACCOUNTS
  2. android.permission.READ_CONTACTS

Elas podem ser definidas ao clicar no ícone U e definir a
permissão. A Figura 10 mostra como a guia Permissions deverá se
parecer.

Figura 10. Manifesto de permissões do Android

Widget listView usando ListActivity

Este exemplo destina-se a demonstrar outra forma de implementar um
listView. No aplicativo acima, note que nossa atividade principal implementa a classe activity. Ao lidar com widgets listView, algumas vezes a classe
ListActivity é melhor, pois tem APIs públicas para
manipular cliques em itens de listas, definir adaptadores de listas,
obter a posição do clique, etc.

Podemos modificar nossa atividade para implementar ListActivity como mostra a Listagem 9.

Listagem 9. Implementação usando ListActivity

public class ManageContacts extends ListActivity {
    @Override
    protected void onListItemClick(ListView l, View v,
int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
if(v instanceof TextView)
selectedText.setText(((TextView) v).getText());
}
private CheckBox mCheckBox;
private boolean mShowStarred;
private TextView selectedText;
/** Called when the activity is first created. */
@Override
public void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mCheckBox = (CheckBox) findViewById(R.id.showStarred);
selectedText = (TextView)
findViewById(R.id.selectedContact);
mShowStarred = false;

mCheckBox.setOnCheckedChangeListener(new
CheckChangedListener());

populateContactList();

}

public void populateContactList() {
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
};
String[] selectionArgs = null;
String sortOrder =
ContactsContract.Contacts.DISPLAY_NAME +
" COLLATE LOCALIZED ASC";
String selection = mShowStarred?
ContactsContract.Contacts.STARRED + " ='1'" : null;
Cursor c =
getContentResolver().query(uri, projection,
selection, selectionArgs, sortOrder);

String[] fields = new String[] {
ContactsContract.Data.DISPLAY_NAME
};
ListAdapter adapter = new
SimpleCursorAdapter(this,
R.layout.contactitem, c, fields, new
int[]{R.id.contactItem});
setListAdapter(adapter);

}

private class CheckChangedListener
implements OnCheckedChangeListener {

@Override
public void onCheckedChanged(CompoundButton
buttonView, boolean isChecked) {
mShowStarred = isChecked;
selectedText.setText("");
populateContactList();
   }
        
    }
}

Note que, aqui, simplesmente implementamos o método onListItemClick de ListActivity, em vez de declarar uma classe anônima para manipular cliques. Também não precisamos nos referir ao widget listView definido em main.xml porque ListActivity presume que o widget listView é definido com um
ID de @android:id/list.

Isto é importante de se observar. Sempre que usarmos ListActivity, teremos que definir o widget listView em main.xml para ter um ID de
@android:id/list. Caso contrário, o ListActivity não saberá a qual listView se referir.

Conclusão

Neste artigo, aprendemos como configurar o Eclipse para
desenvolvimento em Android, e como os valiosos recursos do
Eclipse ajudam em cada etapa ao escrever aplicativos para Android. Também
aprendemos como os aplicativos podem ser facilmente implementados e
testados no emulador do Android – AVD.

Abordamos os notáveis recursos de
um aplicativo do Android usando um exemplo Hello World e aprendemos
sobre os arquivos que compõem um aplicativo Android. Falamos sobre
alguns dos widgets fornecidos pelo Android e vimos seu uso em alguns
exemplos reais.

Agora você deverá estar bem encaminhado para criar um
excelente aplicativo com uma UI organizada. Como primeira etapa, estenda
o aplicativo contacts para implementar a ação de clique em um item de
lista a fim de exibir o número do telefone e os detalhes do contato, e
um botão para chamar o contato selecionado.

Um intento de chamada também
deverá ser definido, juntamente com um filtro de intento, que deverá
implementar a funcionalidade de realização da chamada.

O Android é uma plataforma eficiente para aplicativos
remotos e codificação em tecnologia Java. Juntamente com o Android
Development Tools para Eclipse, ele se torna fácil de ser adotado por
iniciantes.

Sua ampla variedade de widgets, juntamente com sua
capacidade de vincular dinamicamente os elementos da UI à implementação,
fornece uma grande flexibilidade e torna o aplicativo leve, apesar da
UI sofisticada.

Os conceitos de atividades, intentos, provedores de
conteúdo, etc., tornam fácil de gerenciar a UI e os elementos de dados, além
de controlar a vinculação entre eles. Ele também tem um grande conjunto
de APIs de rede a explorar.

Além disso, as APIs do Google fornecem
funcionalidade para mapas, pesquisa e correio, entre outras coisas – que
podem ser facilmente adotadas em um aplicativo do Android. Portanto,
aprofunde-se no maravilhoso mundo do Android e solte sua imaginação.

Recursos

Aprender

Obter produtos e tecnologias

Discutir

  • O
    Newsgroup da Plataforma Eclipse
    deverá ser sua primeira parada para discussão das questões relacionadas
    ao Eclipse. (A seleção deste link ativará seu aplicativo leitor de
    notícias Usenet padrão e abrirá eclipse.platform.)
  • O
    Newsgroup do Eclipse tem muitos recursos para pessoas interessadas no uso e na extensão do Eclipse.

***

artigo publicado originalmente no developerWorks Brasil, por Ayushman Jain

Ayushman Jain trabalha na equipe Eclipse no IBM India Software Labs,
Bangalore, como JDT/Core committer. Ele lidera a iniciativa
Eclipse@campus para propagar o Eclipse em universidades indianas. É
muito interessado no Android como plataforma e encoraja seu uso, devido à
facilidade de desenvolvimento em ambientes familiares do Eclipse. E
também é editor técnico de uma revista para jovens, chamada NOW, em
circulação em Deli, Índia. Para a NOW, ele revisou telefones HTC com
base em Android.

é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com/developerworks/br

Ver perfil