Baixe o app para aproveitar ainda mais
Prévia do material em texto
A n d er so n D u ar te d e A m o ri m 2 0 1 1 A N D R O ID , u m a v is ã o g e ra l ANDROID, uma visão geral – Anderson Duarte de Amorim 2 Conteúdo Introdução ....................................................................................................................... 10 Atividades ....................................................................................................................... 11 Criar uma atividade .................................................................................................... 11 Implementando uma interface de usuário ................................................................... 12 Declarando a atividade no manifesto.......................................................................... 13 O uso de filtros intenção ............................................................................................. 13 Iniciar uma atividade .................................................................................................. 14 Iniciar uma atividade para um resultado..................................................................... 15 Encerrar uma atividade ............................................................................................... 16 Gerenciando o ciclo de atividade................................................................................ 16 Aplicar o ciclo de vida callbacks ................................................................................ 17 Salvando estado de atividade ...................................................................................... 23 Manipulação de alterações na configuração ............................................................... 25 Coordenar as atividades .............................................................................................. 26 Fragmentos ..................................................................................................................... 27 Filosofia de design ...................................................................................................... 27 Criando um fragmento ................................................................................................ 29 DialogFragment ...................................................................................................... 30 ListFragment ........................................................................................................... 31 PreferenceFragment ................................................................................................ 31 Adicionando uma interface de usuário ................................................................... 31 Criando um layout .................................................................................................. 32 Adicionando um fragmento de uma atividade ........................................................ 32 Adicionando um fragmento sem uma interface de usuário (UI) ............................ 34 Gerenciando fragmentos ......................................................................................... 35 Executando transações com fragmento .................................................................. 35 ANDROID, uma visão geral – Anderson Duarte de Amorim 3 Comunicando-se com a atividade ........................................................................... 37 Criar callbacks evento para a atividade .................................................................. 38 Adicionando itens à barra de ação .......................................................................... 39 Manuseio do ciclo de vida do fragmento................................................................ 40 Coordenação com o ciclo de vida de atividade ...................................................... 41 Loaders ........................................................................................................................... 43 Resumo API Loader ................................................................................................... 43 Usando carregadores em um aplicativo ...................................................................... 44 Iniciando um Loader ............................................................................................... 45 Reiniciando o Loader.............................................................................................. 46 Usando callbacks do LoaderManager..................................................................... 47 Exemplo ...................................................................................................................... 50 Tarefas e pilha de execução ............................................................................................ 53 Salvando estado de atividade ...................................................................................... 56 Gerenciando tarefas .................................................................................................... 57 Definição de modos de lançamento ............................................................................ 58 Usando o arquivo de manifesto .................................................................................. 59 Usando as opções de intenções ................................................................................... 61 Manipulação de afinidades ......................................................................................... 62 Limpando a pilha de volta .......................................................................................... 64 Iniciando uma tarefa ................................................................................................... 65 Serviços .......................................................................................................................... 66 O básico ...................................................................................................................... 67 Você deve utilizar um serviço ou um thread? ........................................................ 67 Declarando um serviço no manifesto ..................................................................... 69 Criando um serviço iniciado ....................................................................................... 70 Segmentação Android 1.6 ou inferior..................................................................... 70 ANDROID, uma visão geral – Anderson Duarte de Amorim 4 Estendendo a classe IntentService .......................................................................... 71 Estendendo a classe de serviço ............................................................................... 73 Iniciando um serviço .............................................................................................. 77 Parando um serviço ................................................................................................ 77 Criando um serviço vinculado .................................................................................... 78 Enviando notificações para o usuário ......................................................................... 79 Executando um serviço em primeiro plano ................................................................ 79 Gerenciando ciclo de vida de um serviço ................................................................... 80 Aplicando o ciclo de vida dos callbacks ................................................................. 81 Serviços vinculados ........................................................................................................ 84 O básico ...................................................................................................................... 84 Vinculação a um serviço iniciado ...........................................................................84 Criando um serviço ligado .......................................................................................... 85 Estendendo a classe Binder .................................................................................... 87 Usando um Messenger ........................................................................................... 90 Vinculação a um serviço............................................................................................. 93 Notas adicionais ...................................................................................................... 95 Gerenciando o ciclo de vida de um serviço de associação ......................................... 96 Processos e threads ......................................................................................................... 98 Processos .................................................................................................................... 98 Ciclo de vida do processo ....................................................................................... 99 Thread ....................................................................................................................... 102 Threads funcionais ................................................................................................ 103 Usando AsyncTask ............................................................................................... 104 Métodos de Thread-safe ....................................................................................... 106 Comunicação entre processos ................................................................................... 106 Interface de usuário ...................................................................................................... 108 ANDROID, uma visão geral – Anderson Duarte de Amorim 5 Hierarquia de view.................................................................................................... 108 Como o Android desenha views ........................................................................... 109 Layout ....................................................................................................................... 111 Widgets ..................................................................................................................... 112 Eventos UI ................................................................................................................ 114 Menus ....................................................................................................................... 114 Tópicos Avançados .................................................................................................. 115 Adaptadores .......................................................................................................... 115 Estilos e Temas ..................................................................................................... 116 Declarando Layout ....................................................................................................... 117 Escreve o XML ......................................................................................................... 118 Carregar os recursos XML ....................................................................................... 119 Atributos ................................................................................................................... 119 ID .......................................................................................................................... 119 Parâmetros de layout ............................................................................................ 120 Posição de Layout ..................................................................................................... 122 Tamanho, padding e margin ..................................................................................... 122 Criando Menus ............................................................................................................. 124 Menu de Opções ................................................................................................... 124 Menu de Contexto ................................................................................................ 124 Submenu ............................................................................................................... 124 Criando um recurso de menu .................................................................................... 124 Inflar um recurso de menu ........................................................................................ 126 Criando um Menu de Opções ................................................................................... 126 Respondendo à ação do usuário............................................................................ 127 Alterando os itens de menu em tempo de execução ............................................. 129 Criando um Menu de Contexto ................................................................................ 129 ANDROID, uma visão geral – Anderson Duarte de Amorim 6 Registre uma ListView ......................................................................................... 130 Criando Submenus .................................................................................................... 132 Outras funções do menu ........................................................................................... 132 Grupos de Menu ................................................................................................... 132 Itens de menu verificados ..................................................................................... 133 As teclas de atalho ................................................................................................ 135 Adicionar intenções em menu dinamicamente ..................................................... 136 Permitindo a sua atividade a ser adicionada para outros menus........................... 137 Usando a barra de ação ................................................................................................. 139 Adicionando a barra de ação .................................................................................... 139 Removendo a barra de ação .................................................................................. 140 Adicionando itens de ação ........................................................................................ 141 Usando o ícone do aplicativo como um item de ação .......................................... 142 Usando o ícone do aplicativo para navegar "para cima" ...................................... 143 Adicionando uma exibição de ação .......................................................................... 144 Adicionando abas ..................................................................................................... 146 Adicionando de navegação drop-down .................................................................... 149 Exemplo de SpinnerAdapter e OnNavigationListener ......................................... 150 Estilizando a barra de ação ....................................................................................... 152 Criando caixas de diálogo............................................................................................. 156 Mostrando uma caixa de diálogo .............................................................................. 156 Dispensar um diálogo ............................................................................................... 158 Usando demissão de receptores ............................................................................ 158 Criando um AlertDialog ........................................................................................... 159 Adicionando botões.............................................................................................. 160 Adicionando uma lista .......................................................................................... 161 Adicionando caixas de seleção e botões de rádio ................................................. 161 ANDROID, uma visão geral – Anderson Duarte de Amorim 7 Criar um ProgressDialog .......................................................................................... 162 Mostrando uma barra de progresso ...................................................................... 163 Criando uma caixa de diálogo personalizada ........................................................... 166 Manipulando eventos de UI .......................................................................................... 169 Os ouvintes de eventos ............................................................................................. 169 Manipuladores de eventos ........................................................................................ 172 Modo de toque .......................................................................................................... 173 Manipulação do foco ................................................................................................ 174 Notificar o usuário ........................................................................................................ 176 Notificação brinde .................................................................................................... 176 Criando notificações brinde .................................................................................. 177 Notificação na barra de status ................................................................................... 179 Criação de notificações da barra de status ............................................................ 180 Notificação de diálogo .............................................................................................. 189 Aplicando estilos e temas ............................................................................................. 190 Definição de estilos .................................................................................................. 190 Herança ................................................................................................................. 191 Propriedades do estilo ........................................................................................... 192 Aplicando estilos e temas para a interface do usuário .............................................. 194 Aplicar um estilo a uma view ............................................................................... 194 Aplicar um tema a uma atividade ou aplicação .................................................... 195 Selecione um tema baseado na versão de plataforma........................................... 196 Usando estilos e temas da plataforma ...................................................................... 196 Recursos de aplicação ................................................................................................... 198 Armazenamento de dados ............................................................................................. 201 Utilizando preferências compartilhadas ................................................................... 201 Preferências do usuário ......................................................................................... 202 ANDROID, uma visão geral – Anderson Duarte de Amorim 8 Usando o armazenamento interno ............................................................................ 203 Salvando os arquivos de cache ............................................................................. 204 Usando o armazenamento externo ............................................................................ 205 Verificar a disponibilidade dos meios .................................................................. 205 Acessando arquivos em armazenamento externo ................................................. 206 Escondendo seus arquivos a partir da Media Scanner .......................................... 206 Como salvar arquivos que devem ser compartilhados ......................................... 206 Salvando os arquivos de cache ............................................................................. 207 Utilizando bancos de dados ...................................................................................... 208 Banco de dados de depuração ............................................................................... 209 Usando uma conexão de rede ................................................................................... 209 Artigos .......................................................................................................................... 210 Acessibilidade ........................................................................................................... 210 Linguagens e recursos .......................................................................................... 210 Linguagens e localidade ....................................................................................... 211 Fazendo o dispositivo „falar‟ ................................................................................ 211 Interface .................................................................................................................... 213 Toque .................................................................................................................... 213 Gestos ....................................................................................................................... 216 Método de entrada de dados ................................................................................. 216 Criando um método de entrada de dados ............................................................. 223 Ações de desenhos .................................................................................................... 226 Truques de layout: criando layouts eficientes .......................................................... 229 Truques de layout: usando ViewStub ....................................................................... 234 Truques de layout: mesclando layouts...................................................................... 237 ListView, uma otimização ........................................................................................ 244 Live folders ............................................................................................................... 247 ANDROID, uma visão geral – Anderson Duarte de Amorim 9 Live Wallpapers ........................................................................................................ 252 Usando webViews .................................................................................................... 254 Funcionalidades ........................................................................................................ 255 Caixa de pesquisa ................................................................................................. 255 Sistema ..................................................................................................................... 258 Alocação de memória ........................................................................................... 258 Zipaling oferece uma otimização fácil ................................................................. 260 Nota .............................................................................................................................. 263 Fontes ........................................................................................................................... 263 Fontes das imagens ...................................................................................................266 Fontes dos artigos ..................................................................................................... 266 ANDROID, uma visão geral – Anderson Duarte de Amorim 10 Introdução O Android é um software open-source criado para os celulares e outros dispositivos. O Android Open Source Project (AOSP), liderado pelo Google, está encarregado da manutenção e desenvolvimento do Android. Muitos fabricantes de dispositivos trouxeram ao mercado de dispositivos rodando o Android, e eles são disponíveis ao redor do mundo. O objetivo principal é construir uma plataforma de software excelente para usuários de todos os dias. Uma série de empresas empenhou muitos engenheiros para atingir esse objetivo, e o resultado é uma produção total de produtos de consumo de qualidade, cuja fonte é aberta para customização e portabilidade. Você pode encontrar mais informações sobre o Android a partir destas páginas abaixo: Filosofia de projeto e objetivos Interagindo com o projeto Compatibilidade com Android Informações sobre licenciamento ANDROID, uma visão geral – Anderson Duarte de Amorim 11 Atividades Uma Activity é um componente do aplicativo que fornece uma tela com a qual os usuários podem interagir, a fim de fazer algo, como discar o telefone, tirar uma foto, enviar um e-mail, ou ver um mapa. Para cada atividade é dada uma janela na qual se desenha sua interface de usuário. A janela normalmente preenche a tela, mas pode ser menor do que a tela e flutuar em cima de outras janelas. Um aplicativo normalmente consiste de múltiplas atividades que são frouxamente ligadas uns aos outros. Normalmente uma atividade em um aplicativo é especificada como a atividade “principal", que é apresentada ao usuário ao iniciar o aplicativo pela primeira vez. Cada atividade pode começar outra atividade, a fim de executar ações diferentes. Cada vez que começa uma nova atividade, a atividade anterior é interrompida, mas o sistema preserva a atividade em uma pilha (a "pilha de volta"). Quando uma nova atividade começa, é empurrada para a pilha de volta e leva o foco do usuário. A pilha de volta usa "last in, first out" como mecanismo de fila, então, quando o usuário está em uma atividade e pressione a tecla BACK, a atividade é removida da pilha (e destruída) e retoma a atividade anterior. Quando uma atividade é parada por causa de uma nova atividade, há uma notificação da alteração no estado através de métodos de retorno da atividade do ciclo de vida. Existem vários métodos de retorno que uma atividade possa receber, devido a uma mudança em seu estado. Por exemplo, quando parado, sua atividade deve liberar todos os objetos grandes, como conexões de rede ou banco de dados. Quando a atividade recomeça, você pode readquirir os recursos necessários e retomar as ações que foram interrompidas. Estas transições de estado são todos parte do ciclo de atividade. Criar uma atividade Para criar uma atividade, você deve criar uma subclasse da Activity (ou uma subclasse existente do mesmo). Em sua subclasse, você precisa implementar métodos de callback que chama o sistema quando ocorrem as transições de atividade entre diversos estados do seu ciclo de vida, como quando a atividade está sendo criada, parou, recomeçou, ou foi destruída. Os dois métodos de retorno mais importantes são: onCreate(): Você deve implementar este método. O sistema chama isso ao criar a sua atividade. Dentro de sua aplicação, você deve inicializar os componentes essenciais de ANDROID, uma visão geral – Anderson Duarte de Amorim 12 sua atividade. Mais importante, este é o lugar onde você deve chamar setContentView() para definir o layout para a atividade do usuário a interface. onPause(): O sistema chama este método como o primeiro indício de que o usuário está saindo de sua atividade (embora nem sempre signifique que a atividade está sendo destruída). Isso geralmente é onde você deve cometer quaisquer alterações que devem ser mantidas para além da sessão atual do usuário (porque o usuário pode não voltar). Existem vários métodos de retorno do ciclo de vida de outros que você deve usar a fim de proporcionar uma experiência de usuário mais fluida entre as atividades e manipular interrupções inesperadas que causem a sua atividade a ser interrompida e até mesmo destruída. Implementando uma interface de usuário A interface de usuário para uma determinada atividade é assegurada por uma hierarquia de pontos de vista - objetos derivam da classe View. Cada exibição controla um determinado espaço retangular dentro da janela da atividade e pode responder a interação do usuário. Por exemplo, uma visão pode ser um botão que inicia uma ação quando o usuário tocá-la. Android fornece um número de pontos de vista prontos que você pode usar para criar e organizar seu layout. "Widgets" são vistas que proporcionam um visual (interativo) de elementos para a tela, como um botão, um campo texto, checkbox, ou apenas uma imagem. "Esquemas" são pontos de vista derivados de ViewGroup que fornecem um modelo de layout exclusivo para a estrutura derivada, como um layout linear, um layout de grade, ou a disposição relativa. Você pode criar uma subclasse da View e ViewGroup (ou subclasses existentes) para criar seus próprios widgets e layouts e aplicá-las ao seu layout atividade. A maneira mais comum para definir um layout usando pontos de vista é com um arquivo XML salvo disposição em recursos do seu aplicativo. Dessa forma, você pode manter o design da sua interface de usuário separadamente do código fonte que define o comportamento da atividade. Você pode definir o layout da interface do usuário para a sua atividade com setContentView(), passando a identificação do recurso para o layout. No entanto, você também pode criar novas Views no seu código de atividade e construir ANDROID, uma visão geral – Anderson Duarte de Amorim 13 uma hierarquia de vista através da inserção de novos Views em um ViewGroup, em seguida, usar esse esquema, passando a raiz ViewGroup para setContentView(). Declarando a atividade no manifesto Você deve declarar a sua atividade no arquivo de manifesto para que ele seja acessível para o sistema. Para declarar sua atividade, abra o arquivo e adicione um <activity> como um filho do <application>. Por exemplo: <manifest ... > <application ... > <activity android:name=".ExampleActivity" /> ... </application ... > ... </manifest > Existem vários outros atributos que podem ser incluídos nesse elemento, para definir propriedades, como o rótulo para a atividade, um ícone para a atividade, ou um tema ao estilo de interface do usuário da atividade. O uso de filtros intenção Um <activity> também pode especificar filtros diferentes, usando o <intent-filter>, a fim de declarar como outros componentes de aplicação podem ativá-lo. Quando você cria um novo aplicativo usando as ferramentas do Android SDK, a atividade de topo que é criada para você automaticamente inclui a intenção de filtro que declara a atividade e responde à ação "principal" e deve ser colocado no "lançador" da categoria. A intenção parece filtro como este: <activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> O elemento <action> especifica que este é o "principal ponto de entrada" para o aplicativo. O elemento <category> especifica que esta atividade deve ser listada no sistema lançador de aplicação. ANDROID, uma visão geral – Anderson Duarte de Amorim 14 Se você pretende que o seu aplicativo seja auto-suficiente e não permita que outras aplicações ativem as suas atividades, então você não precisa de nenhum outro filtrode intenção. Apenas uma atividade deve ter a ação "principal" e "lançador" da categoria, como no exemplo anterior. Atividades que você não deseja disponibilizar para outros aplicativos não devem ter a intenção de filtros e você pode iniciá-los usando as intenções explícitas. No entanto, se você quiser a sua atividade para responder às intenções implícitas que são entregues a partir de outras aplicações (e suas próprias), então você deve definir filtros de intenção adicional para a sua atividade. Para cada tipo de intenção para o qual pretende responder, você deve incluir um <intent-filter> que inclui um elemento <action> e, opcionalmente, um elemento <category> e/ou um <data>. Estes elementos especificam o tipo de intenções para que sua atividade possa responder. Iniciar uma atividade Você pode iniciar outra atividade, chamando startActivity(), passando-lhe uma Intent que descreve a atividade que deseja iniciar. A intenção especifica qualquer atividade exatamente o que deseja iniciar ou descreve o tipo de ação que deseja executar (e o sistema seleciona a atividade adequada para você, que pode mesmo ser de um aplicativo diferente). A intenção também pode transportar pequenas quantidades de dados a serem utilizados pela atividade que é iniciada. Quando se trabalha dentro de sua própria aplicação, muitas vezes você precisa simplesmente lançar uma atividade conhecida. Você pode fazer isso criando uma intenção que define explicitamente a atividade que deseja iniciar, usando o nome da classe. Por exemplo, aqui está como uma atividade inicia outra atividade denominada SignInActivity: Intent intent = new Intent(this, SignInActivity.class); startActivity(intent); No entanto, sua aplicação pode também querer executar alguma ação, como enviar um e-mail, mensagem de texto, ou atualização de status, usando dados de sua atividade. Neste caso, sua aplicação não pode ter as suas próprias atividades para realizar tais ações, para que você possa aproveitar ao invés das atividades previstas por outras aplicações no dispositivo, que pode executar as ações para você. Este é o lugar onde as ANDROID, uma visão geral – Anderson Duarte de Amorim 15 intenções são realmente valiosas, você pode criar uma intenção que descreve uma ação que deseja executar e o sistema inicia a atividade adequada a partir de outro aplicativo. Se houver múltiplas atividades que podem manipular a intenção, então o usuário pode selecionar qual usar. Por exemplo, se você quer permitir que o usuário envie uma mensagem de e-mail, você pode criar a seguinte intenção: Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); startActivity(intent); O EXTRA_EMAIL extra adicionado é uma matriz de seqüência de endereços de e-mail para onde o e-mail deve ser enviado. Quando um aplicativo de e-mail responde a esta intenção, ele lê a matriz de cadeia prevista na „extra‟ e as coloca no campo "Para" do formulário de composição de e-mail. Iniciar uma atividade para um resultado Às vezes, você pode querer receber um resultado da atividade que você começar. Nesse caso, iniciar a atividade, chamando startActivityForResult() (em vez de startActivity() ). Para então receber o resultado da atividade subseqüente, aplicar o onActivityResult(), método de retorno. Quando a atividade subseqüente é feita, ele retorna um resultado de uma Intent para o seu método onActivityResult(). Por exemplo, talvez você queira que o usuário escolha um de seus contatos, para que sua atividade pode fazer algo com as informações desse contato. Veja como você pode criar uma intenção e manipular o resultado: private void pickContact() { // Create an intent to "pick" a contact, as defined by the content provider URI Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); startActivityForResult(intent, PICK_CONTACT_REQUEST); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // If the request went well (OK) and the request was PICK_CONTACT_REQUEST if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { // Perform a query to the contact's content provider for the contact's name Cursor cursor = getContentResolver().query(data.getData(), new String[] {Contacts.DISPLAY_NAME}, null, null, null); if (cursor.moveToFirst()) { // True if the cursor is not empty int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); String name = cursor.getString(columnIndex); ANDROID, uma visão geral – Anderson Duarte de Amorim 16 // Do something with the selected contact's name... } } } Este exemplo mostra a lógica básica que você deve usar seu método onActivityResult() para lidar com um resultado de atividade. A primeira condição verifica se a solicitação foi bem-sucedida, se for, então o resultCode será RESULT_OK e se a solicitação para que este resultado está respondendo é conhecido, neste caso, o requestCode coincide com o segundo parâmetro enviada com startActivityForResult(). De lá, o código manipula o resultado de atividade, consultando os dados retornados de uma Intent. O que acontece é, um ContentResolver executa uma consulta contra um provedor de conteúdo, que retorna um Cursor que permite que os dados consultados possam serem lidos. Encerrar uma atividade Você pode encerrar uma atividade chamando seu método finish(). Você também pode encerrar uma atividade separada que já começou chamando finishActivity() . Nota: Na maioria dos casos, você não deve terminar explicitamente uma atividade com estes métodos. Como discutido na seção seguinte sobre o ciclo de vida de atividade, o sistema Android gerencia a vida de uma atividade para você, então você não precisa terminar a sua própria atividade. Chamar esses métodos pode afetar negativamente a experiência do usuário e só deve ser usado quando você realmente não quer que o usuário retorne a esta instância da atividade. Gerenciando o ciclo de atividade Gerenciar o ciclo de vida de suas atividades através da implementação de métodos de retorno é essencial para desenvolver uma aplicação forte e flexível. O ciclo de vida de uma atividade está diretamente afetada pela sua associação com outras atividades, a sua missão e voltar à pilha. Uma atividade pode existir em três estados, essencialmente: Retomado: A atividade está em primeiro plano da tela e tem o foco do usuário. (Esse estado é também por vezes referido como "run".) ANDROID, uma visão geral – Anderson Duarte de Amorim 17 Em pausa: Outra atividade está em primeiro plano e tem foco, mas este é ainda visível. Ou seja, outra atividade é visível na parte superior de um presente e que a atividade é parcialmente transparente ou não cobre a tela inteira. Uma atividade em pausa está completamente viva (o objeto Activity é mantido na memória, ele mantém todas as informações do estado e membro, e permanece preso ao gerenciador de janelas), mas pode ser morta pelo sistema em situações de pouca memória. Parado: A atividade é totalmente obscurecida por outra atividade (a atividade está agora em "background"). A atividade parada também está ainda viva (o objeto Activity é mantido na memória, ele mantém todas as informações do estado e membro, mas não está ligado ao gerenciador de janelas). No entanto, já não é visível para o usuário e pode ser morto pelo sistema quando a memória é necessária em outro lugar. Se uma atividade está em pausa ou parada, o sistema pode retirá-la da memória, quer por pedir para terminar (chamando seu finish()), ou simplesmente matar o processo. Quando a atividade é aberta novamente (depois de ter sido concluído ou morto), ela deve ser criada por toda parte. Aplicar o ciclo de vida callbacks Quando uma atividadetransita entrando e saindo dos diferentes estados descritos acima, ele é notificado através de vários métodos de retorno. Todos os métodos de callback são ganchos que você pode substituir para fazer um trabalho adequado quando o estado da sua atividade muda. A atividade seguinte inclui cada um dos métodos de ciclo de vida fundamentais: public class ExampleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // The activity is being created. } @Override protected void onStart() { super.onStart(); // The activity is about to become visible. } @Override protected void onResume() { super.onResume(); // The activity has become visible (it is now "resumed"). } ANDROID, uma visão geral – Anderson Duarte de Amorim 18 @Override protected void onPause() { super.onPause(); // Another activity is taking focus (this activity is about to be "paused"). } @Override protected void onStop() { super.onStop(); // The activity is no longer visible (it is now "stopped") } @Override protected void onDestroy() { super.onDestroy(); // The activity is about to be destroyed. } } Nota: A implementação destes métodos do ciclo de vida deve sempre chamar a implementação da superclasse antes de fazer qualquer trabalho, conforme mostrado nos exemplos acima. Juntos, esses métodos definem o ciclo de vida de uma atividade. Ao implementar esses métodos, você pode monitorar três loops aninhados no ciclo de vida de atividade: A vida inteira de uma atividade acontece entre a chamada para onCreate() e a chamada para onDestroy(). Sua atividade deve executar a instalação do "Estado" global (tal como a definição de layout) em onCreate(), e liberar todos os recursos remanescentes em onDestroy(). Por exemplo, se a sua atividade tem um segmento em execução em segundo plano para transferir os dados da rede, ele pode criar esse tópico em onCreate() e depois parar o segmento em onDestroy(). O tempo de vida visível de uma atividade acontece entre a chamada para onStart() e a chamada para onStop(). Durante este tempo, o usuário pode ver a atividade na tela e interagir com ele. Por exemplo, onStop() é chamado quando inicia uma nova atividade e esta não é mais visível. Entre estes dois métodos, você pode manter os recursos que são necessários para mostrar a atividade para o usuário. Por exemplo, você pode registrar um BroadcastReceiver em onStart() para monitorar as mudanças que impactam sua interface do usuário, e cancelar o registro em onStop() quando o usuário não pode mais ver o que você está sendo exibido. O sistema pode chamar onStart() e onStop() várias vezes durante toda a vida útil da atividade, como a atividade se alterna entre visível e oculta para o usuário. ANDROID, uma visão geral – Anderson Duarte de Amorim 19 O tempo de vida do primeiro plano de uma atividade acontece entre a chamada para onResume() e a chamada para onPause(). Durante este tempo, a atividade está na frente de todas as outras atividades na tela e tem foco de entrada do usuário. Uma atividade pode freqüentemente transitar para dentro e fora do plano, por exemplo, onPause() é chamado quando o dispositivo vai dormir ou quando uma caixa de diálogo aparece. O código desses dois métodos deve ser bastante leve, para evitar transições lentas que fazem o usuário esperar. A figura 1 ilustra esses laços e os caminhos de uma atividade que podem levar a esses estados. Figura 1. O ciclo de vida de atividade. ANDROID, uma visão geral – Anderson Duarte de Amorim 20 Tabela 1. Um resumo do ciclo de vida do callback métodos atividade. Método Descrição Killable depois? Seguinte onCreate() Chamado quando a atividade é criada pela primeira vez. Isto é onde você deve fazer tudo do seu conjunto estático normal - criar pontos de vista, vincular dados em listas, e assim por diante. Sempre seguido por onStart() . Não onStart() onRestart() Chamado depois que a atividade foi interrompida, pouco antes de ele ser iniciado novamente. Sempre seguido por onStart() Não onStart() onStart() Chamado imediatamente antes da atividade tornar-se visível para o usuário. Seguido por onResume() se a atividade vem para o primeiro plano, ou onStop() se torna oculto. Não onResume() onResume() Chamado imediatamente antes da atividade passar a interagir com o usuário. Neste ponto, a atividade está no topo da pilha de atividade. Sempre seguido por onPause() . Não onPause() ANDROID, uma visão geral – Anderson Duarte de Amorim 21 onPause() Chamado quando o sistema está prestes a começar a retomar a outra atividade. Este método é geralmente usado para confirmar as alterações não salvas, dados persistentes, animações stop e outras coisas que podem estar consumindo CPU, e assim por diante. Ele deve fazer tudo o que ele faz muito rapidamente, porque a próxima atividade não será retomada até que ele retorne. Seguidas por onResume() se a atividade retorna para a frente, ou por onStop() se torna invisível para o usuário. Sim onResume() ou onStop() onStop() Chamado quando a atividade já não é visível para o usuário. Isso pode acontecer porque ele está sendo destruído, ou porque outra atividade (seja um existente ou uma nova) foi retomado e está cobrindo-o. Seguidas por onRestart() se a atividade está voltando para interagir com o usuário, ou por onDestroy() se essa atividade está indo embora. Sim onRestart() ou onDestroy() ANDROID, uma visão geral – Anderson Duarte de Amorim 22 onDestroy() Chamado antes que a atividade é destruída. Esta é a chamada final que a atividade irá receber.Poderia ser chamada, quer porque a atividade está acabando (alguém chamado finish() nela), ou porque o sistema está destruindo essa instância da atividade para economizar espaço. Você pode distinguir entre estes dois cenários com o isFinishing(). Sim nada A coluna chamada "killable depois?" indica se o sistema pode matar o processo que acolhe a atividade a qualquer momento após o método retornar, sem executar outra linha. Três métodos são marcados como "sim": (onPause() , onStop() , e onDestroy() ). onPause() é o primeiro dos três, uma vez que a atividade é criada, onPause() é o último método que é garantido para ser chamado antes que o processo pode ser morto, se o sistema deve recuperar a memória em caso de emergência, então onStop() e onDestroy() não podem ser chamados. Portanto, você deve usar onPause() para escrever dados persistentes para armazenamento. No entanto, você deve ser seletivo sobre quais informações devem ser mantidas durante onPause(), porque os procedimentos de bloqueio neste método bloqueiam a passagem para a próxima atividade e retardam a experiência do usuário. Métodos que são marcados como "Não" na coluna killable protegem o processo da atividade de ser morto desde o momento em que são chamados. Assim, uma atividade é killable a partir do momento onPause() e retorna quando onResume() é chamado. Não será novamente killable até onPause() seja novamente chamado e retornado. Nota: uma atividade que não é tecnicamente "killable" por esta definição na tabela 1 ainda pode ser morta pelo sistema, mas isso vai acontecer apenas em circunstâncias extremas, quando não há outro recurso. ANDROID, uma visão geral – Anderson Duarte de Amorim 23 Salvando estado de atividade A introdução à Gestão do Ciclo de Atividade menciona brevemente que, quando uma atividade está em pausa ou parada, o estado da atividade é mantido. Isto é verdade porque a Activity ainda está retida na memória quando estáem pausa ou parada, todas as informações sobre seus membros e estado atuais ainda estão vivos. Assim, qualquer alteração que o usuário fez no âmbito da atividade é retida na memória, de modo que quando a atividade retorna para o primeiro plano (quando ele "retoma"), essas mudanças ainda estão lá. Figura 2. As duas formas em que para a atividade um usuário retorna ao foco com seu estado intacto, quer a atividade é interrompida, e retomada em seguida, o estado de atividade permanece intacta (à esquerda), ou a atividade é destruído, então recriada e a atividade deve restaurar o estado da atividade anterior (direita). No entanto, quando o sistema destrói uma atividade, a fim de recuperar a memória, a Activity é destruída, então o sistema não pode simplesmente continuar com o seu estado intacto. Em vez disso, o sistema deve recriar a Activity se o usuário navega de volta para ele. No entanto, o usuário não sabe que o sistema destrói e recria a atividade e, assim, provavelmente espera que a atividade seja exatamente como era. Nessa situação, ANDROID, uma visão geral – Anderson Duarte de Amorim 24 você pode garantir que informações importantes sobre o estado de atividade são preservadas através da implementação de um método de retorno adicional que permite que você salve as informações sobre o estado de sua atividade e, em seguida, restaura quando o sistema recria a atividade. O método de callback em que você pode salvar informações sobre o estado atual da sua atividade é onSaveInstanceState(). O sistema chama este método antes de fazer a atividade vulnerável a ser destruída e passa-lhe um objeto Bundle. O Bundle é o lugar onde você pode armazenar informações de estado sobre a atividade como pares valor- nome, utilizando métodos como putString(). Então, se o sistema mata a atividade e o usuário navega de volta para sua atividade, o sistema passa o Bundle para onCreate() para que você possa restaurar o estado de atividade que tenha sido guardado durante onSaveInstanceState(). Se não há informações do estado para restaurar, em seguida, o Bundle que passou a onCreate() se torna nulo. Nota: Não há nenhuma garantia de que onSaveInstanceState() será chamado antes de sua atividade ser destruída, porque há casos em que não será necessário salvar o estado (como quando o usuário deixa a sua atividade com a chave de volta, porque a usuário explicitamente encerra as atividades). Se o método for chamado, ele sempre é chamado antes de onStop() e, possivelmente, antes de onPause(). No entanto, mesmo se você não faz nada e não implementar onSaveInstanceState(), alguns estados de atividade são restaurados pela Activity de implementação padrão da classe de onSaveInstanceState(). Especificamente, a implementação padrão chama onSaveInstanceState() para cada View no layout, que permite fornecer informações sobre si que devem ser salvos. Quase todos os widgets no âmbito Android implementam este método, de modo que qualquer mudança visível para o interface do usuário são automaticamente salvas e restauradas quando sua atividade é recriada. Por exemplo, o EditText salva qualquer texto digitado pelo usuário e o CheckBox widget salva se é marcado ou não. O único trabalho exigido por você é fornecer uma identificação única (com o android:id) para cada elemento gráfico que deseja salvar seu estado. Se um elemento não tem um ID, então ele não pode salvar seu estado. Você também pode parar explicitamente de salvar em seu layout seu estado, definindo o android:saveEnabled para "false" ou chamando o setSaveEnabled(). Normalmente, você ANDROID, uma visão geral – Anderson Duarte de Amorim 25 não deve desativar isso, mas você pode caso queira restaurar o estado da atividade de interface diferente. Embora a implementação padrão de onSaveInstanceState() salva as informações úteis sobre a atividade da sua interface, você ainda pode precisar substituí-lo para guardar informações adicionais. Por exemplo, você talvez precise salvar valores de um membro que mudou na vida da atividade (que poderiam se correlacionar com os valores restaurados na interface do usuário, mas os membros que detêm esses valores UI não são restaurados, por padrão). Como a implementação padrão de onSaveInstanceState() ajuda a salvar o estado da interface do usuário, se você substituir o método para salvar informações de estado adicionais, você deve sempre chamar a implementação da superclasse de onSaveInstanceState() antes de fazer qualquer trabalho. Nota: Devido ao onSaveInstanceState() não ser garantido de ser chamado, você deve usá-lo apenas para registrar o estado transiente da atividade (o estado da interface do usuário), você nunca deve usá-lo para armazenar dados persistentes. Em vez disso, você deve usar onPause() para armazenar dados persistentes (como os dados que devem ser salvos em um banco de dados) quando o usuário deixa a atividade. Uma boa maneira de testar a capacidade do seu aplicativo para restaurar seu estado é simplesmente girar o dispositivo para fazer alterações na orientação da tela. Quando da mudança de orientação da tela, o sistema destrói e recria a atividade a fim de aplicar recursos alternativos que possam estar disponíveis para a nova orientação. Por esta razão, é muito importante para sua atividade restaurar completamente o seu estado quando ele é recriado, pois os usuários regularmente giram a tela ao usar aplicações. Manipulação de alterações na configuração Algumas configurações de dispositivo podem mudar durante a execução (tais como a orientação da tela, a disponibilidade de teclado e idioma). Quando essa mudança ocorre, o Android reinicia a atividade em execução (onDestroy() é chamado, seguido imediatamente por onCreate()). O comportamento reiniciar é projetado para ajudar a sua candidatura a se adaptar às novas configurações automaticamente recarregando a sua aplicação com recursos alternativos que você forneceu. Se você projeta sua atividade ANDROID, uma visão geral – Anderson Duarte de Amorim 26 para lidar adequadamente com este evento, vai ser mais resistentes a eventos inesperados no ciclo de atividade. A melhor maneira de lidar com uma mudança de configuração, tais como uma mudança na orientação da tela, é simplesmente preservar o estado do seu aplicativo usando onSaveInstanceState() e onRestoreInstanceState() (ou onCreate() ), como discutido na seção anterior. Coordenar as atividades Quando uma atividade começa outra, ambas experimentam as transições do ciclo de vida. A primeira atividade faz uma pausa e para (embora, não vai parar se ele ainda está visível ao fundo), enquanto a outra atividade é criada. Caso esses dados compartilham atividades salvas em disco ou em outro lugar, é importante entender que a primeira atividade não está completamente parada antes de a segunda ser criada. Pelo contrário, o processo de iniciar o segundo se sobrepõe ao processo de parar o primeiro. A ordem dos retornos do ciclo de vida é bem definida, especialmente quando as duas atividades estão no mesmo processo e está começando um do outro. Aqui está a ordem das operações que ocorrem quando a atividade A começa atividade B: 1. O método onPause() da atividade A é executado. 2. Os métodos onCreate(), onStart(), e onResume() de B são executados em seqüência. (Atividade B agora tem o foco do usuário.) 3. Então, se uma atividade não é mais visível na tela, a sua onStop() é executada. Esta seqüência previsível de callbacks do ciclo de vida permite-lhe gerir a transição de informações de uma atividade para outra. Por exemplo, se você deve escrever em um banco de dados quando a primeira atividade pára para que esta atividade pode lê-lo, então você deve escrever para o banco de dados durante onPause() em vez de durante onStop(). ANDROID, uma visão geral – Anderson Duarte de Amorim 27 Fragmentos Um Fragment representaum comportamento ou uma parte da interface de usuário em uma Activity. Você pode combinar vários fragmentos em uma única atividade para construir uma interface multi-painel e reutilização de um fragmento de atividades múltiplas. Você pode pensar em um fragmento como uma seção modular de uma atividade, que tem seu próprio ciclo de vida, recebe os seus próprios eventos de entrada, e que você pode adicionar ou remover, enquanto a atividade está em execução. Um fragmento deve sempre ser incorporado em uma atividade e o ciclo de vida do fragmento é diretamente afetado pelo ciclo de vida da atividade de acolhimento. Por exemplo, quando a atividade é interrompida, assim são todos os fragmentos nele, e quando a atividade é destruída, assim são todos os fragmentos. No entanto, enquanto uma atividade está em execução (que é na retomada do ciclo de vida do estado), você pode manipular cada fragmento de forma independente, como adicionar ou remover. Quando você executa uma operação deste tipo de fragmento, você também pode adicioná-la a uma pilha de volta que é gerenciado pela atividade de cada pilha de volta na entrada da atividade que é um registro da transação de fragmento que ocorreu. A volta da pilha permite que o usuário possa reverter uma transação (navegar para trás), pressionando a tecla BACK. Quando você adiciona um fragmento como uma parte do seu layout, ele vive em um ViewGroup dentro da view de hierarquia e define o seu próprio layout de pontos de vista. Você pode inserir um fragmento em seu layout declarando o fragmento na atividade de distribuição de arquivos, como <fragment>, ou a partir de seu código de aplicativo, adicionando-o a um já existente ViewGroup. No entanto, um fragmento não é obrigado a fazer parte do esquema de atividade, você também pode utilizar um fragmento como um trabalhador invisível para a atividade. Filosofia de design Android apresenta fragmentos no Android 3.0 (API Level "Honeycomb"), principalmente para apoiar projetos mais dinâmicos e flexíveis de interface do usuário em telas grandes, como os Tablets. Como uma tela de tablet é muito maior do que a de um telefone, há mais espaço para combinar e trocar os componentes de interface do usuário. Fragmentos permitem tais projetos sem a necessidade de gerenciar mudanças ANDROID, uma visão geral – Anderson Duarte de Amorim 28 complexas à hierarquia vista. Ao dividir o layout de uma atividade em fragmentos, você se torna capaz de modificar a aparência da atividade em tempo de execução e preservar essas mudanças em uma pilha de volta que é gerenciada pela atividade. Por exemplo, um aplicativo de notícias pode usar um fragmento para mostrar uma lista de artigos à esquerda e outro fragmento para mostrar um artigo à direita, então os fragmentos aparecem em uma atividade, lado a lado, e cada fragmento tem seu próprio conjunto do ciclo de vida, métodos callback e lidam com seus próprios eventos de entrada do usuário. Assim, em vez de usar uma atividade para selecionar um artigo e outra atividade para ler o artigo, o usuário pode selecionar um artigo e ler tudo dentro da mesma atividade, conforme ilustrado na figura 1. Figura 1. Um exemplo de como dois módulos de interface do usuário que normalmente são separados em duas atividades podem ser combinados em uma atividade, utilizando fragmentos. Um fragmento deve ser um componente modular e reutilizável em sua aplicação. Ou seja, porque o fragmento define o seu próprio layout e seu próprio comportamento, usando seu próprio ciclo de vida callbacks, você pode incluir um fragmento em múltiplas atividades. Isto é especialmente importante porque permite adaptar a sua experiência de usuário para diferentes tamanhos de tela. Por exemplo, você pode incluir vários fragmentos de uma atividade apenas quando o tamanho da tela é suficientemente grande, e, quando não é, lançar atividades distintas que utilizam diferentes fragmentos. Por exemplo, para continuar com o aplicativo de notícia, a aplicação pode inserir dois fragmentos da atividade, quando rodando em uma grande tela extra (um tablet, por exemplo). No entanto, em um tamanho de tela normal (um telefone, por exemplo), não há lugar suficiente para os dois fragmentos, de modo a Atividade A inclui somente o fragmento para a lista de artigos, e quando o usuário seleciona um artigo, ele começa a ANDROID, uma visão geral – Anderson Duarte de Amorim 29 Atividade B, que inclui o fragmento para ler o artigo. Assim, a aplicação suporta os padrões de projeto sugerido na figura 1. Criando um fragmento Figura 2. O ciclo de vida de um fragmento (enquanto a sua atividade está em execução). ANDROID, uma visão geral – Anderson Duarte de Amorim 30 Para criar um fragmento, você deve criar uma subclasse de Fragment (ou uma subclasse existente do mesmo). O código da classe Fragment se parece muito com uma Activity. Ele contém métodos de retorno semelhante a uma atividade, como onCreate(), onStart(), onPause(), e onStop(). Na verdade, se você está convertendo uma aplicação Android existentes para usar fragmentos, você pode simplesmente mover o código de métodos de retorno de sua atividade sobre os métodos de retorno de seus respectivos fragmentos. Normalmente, você deve implementar pelo menos os métodos do ciclo de vida a seguir: onCreate(): O sistema chama isso ao criar o fragmento. Dentro de sua aplicação, você deve inicializar os componentes essenciais do fragmento que pretende manter quando o fragmento é pausado ou parado, então retomado. onCreateView(): O sistema chama isso quando está na hora de extrair o fragmento de sua interface de usuário pela primeira vez. Para desenhar uma interface para o seu fragmento, você deve retornar um View a partir deste método que é a raiz do fragmento do seu layout. Você pode retornar nulo se o fragmento não fornece uma interface do usuário. onPause(): O sistema chama este método como o primeiro indício de que o usuário está saindo do fragmento (embora nem sempre significa que o fragmento está sendo destruído). Isso geralmente é onde você deve cometer quaisquer alterações que devem ser mantidas para além da sessão atual do usuário (porque o usuário pode não voltar). A maioria dos aplicativos devem implementar pelo menos estes três métodos para cada fragmento, mas existem vários métodos de retorno que você também deve usar para lidar com diferentes fases do ciclo de vida do fragmento. Todos os métodos de retorno do ciclo de vida são discutidos mais adiante, na seção sobre o manuseio do Ciclo de Vida do fragmento. Existem também algumas subclasses que você pode querer estender: DialogFragment Mostra uma janela flutuante. Usar essa classe para criar uma caixa de diálogo é uma boa alternativa para usar os métodos auxiliares de diálogo na Activity, porque você pode incorporar um fragmento de diálogo para a volta da pilha de fragmentos gerido pela atividade, permitindo que o usuário retorne a um fragmento rejeitado. ANDROID, uma visão geral – Anderson Duarte de Amorim 31 ListFragment Exibe uma lista de itens que são gerenciados por um adaptador (como um SimpleCursorAdapter), semelhante ao ListActivity. Ele fornece diversos métodos para gerenciar uma lista, como o onListItemClick() de callback para manipular eventos de clique. PreferenceFragment Exibe uma hierarquia de objetos Preference como uma lista, semelhante à PreferenceActivity. Isso é útil quando se cria um "settings" para sua aplicação. Adicionando uma interface de usuário Um fragmento é normalmente usado como parte de uma atividade de interface de usuário e contribui com a sua própria disposição para a atividade. Para fornecer um layout de um fragmento, você deve implementar o onCreateView(), que o sistema Android chama quando é hora do fragmento ser desenhado no layout. A implementação deste método deve retornar um View queé a raiz do fragmento do seu layout. Nota: Se o fragmento é uma subclasse de ListFragment, a implementação padrão retorna um ListView de onCreateView(), então você não precisa implementá-lo. Para devolver um layout de onCreateView(), você pode retirá-lo a partir de um layout de recursos definidos em XML e o desenvolve. Para ajudá-lo a fazê-lo, onCreateView() fornece um LayoutInflater objeto. Por exemplo, aqui está uma subclasse de Fragment que carrega um layout a partir da example_fragment.xml: public static class ExampleFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.example_fragment, container, false); } } ANDROID, uma visão geral – Anderson Duarte de Amorim 32 Criando um layout No exemplo acima, R.layout.example_fragment é uma referência a um recurso chamado layout example_fragment.xml salvo na aplicação dos recursos. O parâmetro passado para onCreateView() é o pai ViewGroup (da atividade do layout), em que o layout do fragmento será inserido. O parâmetro savedInstanceState é um Bundle que fornece dados sobre a instância anterior do fragmento, se o fragmento está sendo retomado. O método inflate() utiliza três argumentos: A identificação de recurso do layout que você deseja inserir. O ViewGroup ser o pai do layout já em utilização. Passando o container é importante para que o sistema possa aplicar os parâmetros de layout para o modo de exibição raiz do layout inflado, especificado pela posição do pai em que ele está indo. Um booleano que indica se o layout desenvolvido deverá ser anexado ao ViewGroup (segundo parâmetro) durante a chamada do procedimento inflate(). (Neste caso, isso é falso, porque o sistema já está inserindo o layout inflado no container de passagem verdade seria criar um grupo de vista redundantes no layout final.) Adicionando um fragmento de uma atividade Normalmente, um fragmento contribui com uma parcela de UI para a atividade de acolhimento, que é incorporado como parte da hierarquia da visão da atividade de conjunto. Há duas maneiras com as quais você pode adicionar um fragmento para o layout de atividade: Declare o fragmento dentro atividade de layout do arquivo. Neste caso, você pode especificar propriedades de layout para o fragmento como se fosse uma exibição. Por exemplo, aqui está o arquivo de layout para uma atividade com dois fragmentos: ANDROID, uma visão geral – Anderson Duarte de Amorim 33 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="com.example.news.ArticleListFragment" android:id="@+id/list" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" /> <fragment android:name="com.example.news.ArticleReaderFragment" android:id="@+id/viewer" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent" /> </LinearLayout> O atributo android:name na <fragment> especifica o Fragment para instanciar no layout. Quando o sistema cria esse layout, ele instancia cada fragmento especificado no layout e chama o onCreateView() para cada um, para recuperar o layout de cada fragmento. O sistema insere a View retornada pelo fragmento diretamente no local do elemento <fragment>. Nota: Cada fragmento requer um identificador único que o sistema pode usar para restaurar o fragmento se a atividade for reiniciada (e que você pode usar para capturar o fragmento para realizar transações, como removê-lo). Existem três formas para fornecer uma identificação de um fragmento: o Forneça o android:id com um ID único. o Forneça o android:tag com uma string única. o Se você não fornecer nenhum dos dois anteriores, o sistema utiliza a identificação de exibição de recipiente. Ou então, programaticamente adicionar o fragmento de um já existente ViewGroup . A qualquer momento, enquanto sua atividade está sendo executada, você pode adicionar fragmentos ao seu layout. Você só precisa especificar um ViewGroup para colocar o fragmento. ANDROID, uma visão geral – Anderson Duarte de Amorim 34 Para fazer transações em sua atividade (como adicionar, remover ou substituir um fragmento), você deve usar as APIs do FragmentTransaction. Você pode obter uma instância de FragmentTransaction de sua Activity como esta: FragmentManager fragmentManager = getFragmentManager() FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); Você pode então adicionar um fragmento ao usar o método add(), especificando o fragmento a adicionar e a visão para inseri-lo. Por exemplo: ExampleFragment fragment = new ExampleFragment(); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit(); O primeiro argumento passado para add() é o ViewGroup em que o fragmento deve ser colocado, especificado por identificação do recurso, e o segundo parâmetro é o fragmento a acrescentar. Depois que você fizer as alterações com FragmentTransaction , você deve chamar commit() para que as alterações tenham efeito. Adicionando um fragmento sem uma interface de usuário (UI) Os exemplos acima mostram como adicionar um fragmento de sua atividade, a fim de fornecer uma interface do usuário. No entanto, você também pode usar um fragmento para fornecer um comportamento de fundo para a atividade sem a apresentação da interface do usuário. Para adicionar um fragmento sem uma interface de usuário, adicione o fragmento da atividade usando add(Fragment, String) (fornecimento de uma única seqüência de "tag" para o fragmento, ao invés de um ID). Isso adiciona o fragmento, mas, porque não está associada a um ponto de vista do layout atividade, ele não recebe uma chamada para onCreateView(). Assim você não precisa implementar esse método. Fornecendo uma tag string para o fragmento não é estritamente para os fragmentos não- UI. Você também pode fornecer etiquetas de seqüência de fragmentos que possuem uma interface de usuário, mas se o fragmento não possui uma interface de usuário, a tag string é o único caminho para identificá-lo. Se você deseja obter o fragmento da atividade posterior, você precisa usar findFragmentByTag(). ANDROID, uma visão geral – Anderson Duarte de Amorim 35 Gerenciando fragmentos Para gerenciar os fragmentos em sua atividade, você precisará usar FragmentManager. Para obtê-lo, chame getFragmentManager() em sua atividade. Algumas coisas que você pode fazer com FragmentManager incluem: Obter fragmentos que existem na atividade, com findFragmentById() (para os fragmentos que fornecem uma interface de usuário no layout de atividade) ou findFragmentByTag() (para os fragmentos que fazem ou não uma interface do usuário). Retirar fragmentos da pilha, com popBackStack() (simulando um comando BACK pelo usuário). Registre-se um ouvinte de alteração de parte de trás da pilha, com addOnBackStackChangedListener(). Conforme demonstrado na seção anterior, você também pode usar FragmentManager para abrir uma FragmentTransaction, que lhe permite realizar transações, tais como adicionar e remover fragmentos. Executando transações com fragmento Uma das grandes novidades sobre o uso de fragmentos em sua atividade é a capacidade de adicionar, remover, substituir e realizar outras ações com eles, em resposta à interação do usuário. Cada conjunto de alterações que comprometem a atividade é chamado detransação e você pode executar um usando APIs em FragmentTransaction. Você também pode salvar cada transação na pilha gerenciada pela atividade, permitindo ao usuário navegar para trás através das mudanças no fragmento (semelhante ao navegar para trás por meio de atividades). Você pode adquirir uma instância de FragmentTransaction do FragmentManager como este: FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); Cada transação é um conjunto de mudanças que se deseja realizar, ao mesmo tempo. Você pode configurar todas as alterações que pretendem efetuar uma operação ANDROID, uma visão geral – Anderson Duarte de Amorim 36 determinada utilizando métodos como add(), remove(), e replace(). Em seguida, para aplicar a operação para a atividade, você deve chamar commit(). Antes de chamar commit(), no entanto, você pode querer chamar addToBackStack(), a fim de acrescentar a operação a uma volta da pilha de transações. Esta volta na pilha é gerida pela atividade e permite que ao usuário retornar ao estado de fragmento anterior, pressionando a tecla BACK. Por exemplo, aqui está como você pode substituir um fragmento a outro e preservar o estado anterior da pilha de volta: // Create new fragment and transaction Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit(); Neste exemplo, newFragment substitui qualquer fragmento (se houver) atualmente no contêiner de layout identificado pelo R.id.fragment_container ID. Ao chamar addToBackStack(), é salvado na pilha de volta a operação para que o usuário possa anular a operação e trazer de volta o fragmento anterior pressionando a tecla BACK. Se você adicionar várias alterações à operação (como um outro add() ou remove()) e chamar addToBackStack(), então todas as mudanças aplicadas antes de chamar commit() são adicionados à volta da pilha como uma única operação e a tecla BACK irá inverter-los todos juntos. A ordem na qual você adiciona as alterações em um FragmentTransaction não importa, exceto: Você deve chamar commit() por último. Se você está adicionando vários fragmentos para o mesmo recipiente, então a ordem em que você adicioná-los determina a ordem em que aparecem na hierarquia. ANDROID, uma visão geral – Anderson Duarte de Amorim 37 Se você não chamar addToBackStack() quando você executar uma operação que remove um fragmento, em seguida, esse fragmento é destruído quando a transação for confirmada e o usuário não pode navegar de volta para ela. Considerando que, se você chamar addToBackStack() quando da remoção de um fragmento, o fragmento é interrompido e será retomado se o usuário navega de volta. Dica: Para cada transação, você pode aplicar uma animação de transição, chamando setTransition() antes do commit(). Chamar commit() não executa a operação imediatamente. Em vez disso, ele agenda a execução no segmento da atividade de interface do usuário (a thread "main"), logo que o segmento for capaz de fazê-lo. Se necessário, no entanto, você pode chamar executePendingTransactions() no seu segmento de interface do usuário para executar imediatamente as operações apresentadas por commit(). Fazer isso geralmente não é necessário a menos que a transação é uma dependência para o emprego em outros segmentos. Cuidado: você pode cometer uma transação usando commit() apenas antes da atividade salvar seu estado (quando o usuário deixa a atividade). Se a tentativa for cometer depois desse ponto, uma exceção será lançada. Isso ocorre porque o estado, após a confirmação, pode ser perdido se a atividade precisa ser restaurada. Para as situações em que não tem problema você perder o commit, use commitAllowingStateLoss(). Comunicando-se com a atividade Ainda que um Fragment seja implementado como um objeto que é independente de uma Activity e pode ser usado dentro de múltiplas atividades, uma determinada instância de um fragmento está diretamente ligada à atividade que o contém. Especificamente, o fragmento pode acessar a instância Activity com getActivity() e facilmente realizar tarefas como encontrar um ponto de vista do esquema de atuação: View listView = getActivity().findViewById(R.id.list); Da mesma forma, sua atividade pode chamar métodos no fragmento através da aquisição de uma referência para o Fragment de FragmentManager, usando findFragmentById() ou findFragmentByTag(). Por exemplo: ANDROID, uma visão geral – Anderson Duarte de Amorim 38 ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment); Criar callbacks evento para a atividade Em alguns casos, você pode precisar de um fragmento de compartilhar eventos com a atividade. Uma boa maneira de fazer isso é definir uma interface de retorno no interior do fragmento e exigem que a atividade de acolhimento implemente-a. Quando a atividade recebe uma chamada através da interface, ela pode compartilhar a informação com outros fragmentos no layout conforme necessário. Por exemplo, se um aplicativo de notícias tem dois fragmentos de uma atividade e um mostra uma lista de artigos (fragmento A) e outro mostra um artigo (fragmento B), então um fragmento deve informar a atividade quando um item da lista é escolhido de modo que pode dizer ao fragmento B para exibir o artigo. Neste caso, a interface OnArticleSelectedListener é declarada dentro de um fragmento: public static class FragmentA extends ListFragment { ... // Container Activity must implement this interface public interface OnArticleSelectedListener { public void onArticleSelected(Uri articleUri); } ... } Em seguida, a atividade que hospeda o fragmento implementa a OnArticleSelectedListener e substitui onArticleSelected() para notificar o fragmento B do evento a partir do fragmento A. Para garantir que a atividade de acolhimento implemente essa interface, um fragmento do método onAttach() de retorno (que chama o sistema quando adicionando o fragmento para a atividade) instancia uma instância de OnArticleSelectedListener pelo casting da Activity que é passado para onAttach(): public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnArticleSelectedListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener"); } ANDROID, uma visão geral – Anderson Duarte de Amorim 39 } ... } Se a atividade não tenha aplicado a interface, então o fragmento lança um ClassCastException. Em caso de sucesso, o membro mListener mantém uma referência para a implementação da atividade de OnArticleSelectedListener, de modo que um fragmento pode compartilhar eventos com a atividade, chamando os métodos definidos pela interface OnArticleSelectedListener. Por exemplo, se um fragmento é uma extensão do ListFragment, cada vez que o usuário clica em um item da lista, o sistema chama onListItemClick() no fragmento, o que chama onArticleSelected() para compartilhar o evento com a atividade: public static class FragmentA extends ListFragment { OnArticleSelectedListener mListener; ... @Override public void onListItemClick(ListView l, View v, int position, long id) { // Append the clicked item's row ID with the content
Compartilhar