• Nenhum resultado encontrado

Android - Uma Visão Geral

N/A
N/A
Protected

Academic year: 2021

Share "Android - Uma Visão Geral"

Copied!
267
0
0

Texto

(1)

A

nders

on

Duar

te de A

mo

rim

2011

ANDROI

D, uma vi

são

gera

l

(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

(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

(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

(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

(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

(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

(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

(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

(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

(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

(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

(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.

(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 filtro de 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 =newIntent(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

(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 =newIntent(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:

privatevoid pickContact(){

// Create an intent to "pick" a contact, as defined by the content provider URI Intent intent =newIntent(Intent.ACTION_PICK,Contacts.CONTENT_URI);

startActivityForResult(intent, PICK_CONTACT_REQUEST); }

@Override

protectedvoid 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(),

newString[]{Contacts.DISPLAY_NAME},null,null,null);

if(cursor.moveToFirst()){// True if the cursor is not empty

int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);

(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".)

(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 atividade transita 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:

publicclassExampleActivityextendsActivity{

@Override

publicvoid onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

// The activity is being created. }

@Override

protectedvoid onStart(){

super.onStart();

// The activity is about to become visible. }

@Override

protectedvoid onResume(){

super.onResume();

// The activity has become visible (it is now "resumed"). }

(18)

@Override

protectedvoid onPause(){

super.onPause();

// Another activity is taking focus (this activity is about to be "paused"). }

@Override

protectedvoid onStop(){

super.onStop();

// The activity is no longer visible (it is now "stopped") }

@Override

protectedvoid 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.

(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.

(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() .

(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

(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.

(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,

(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ê

(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

(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().

(27)

Fragmentos

Um Fragment representa um 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

(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

(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

(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.

(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:

publicstaticclassExampleFragmentextendsFragment{

@Override

publicView onCreateView(LayoutInflater inflater,ViewGroup container,

Bundle savedInstanceState){

// Inflate the layout for this fragment

return inflater.inflate(R.layout.example_fragment, container,false);

} }

(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:

(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.

(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().

(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 de transaçã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

(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 =newExampleFragment();

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.

(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:

(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:

publicstaticclassFragmentAextendsListFragment{

...

// Container Activity must implement this interface publicinterfaceOnArticleSelectedListener{

publicvoid 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():

publicstaticclassFragmentAextendsListFragment{

OnArticleSelectedListener mListener;

...

@Override

publicvoid onAttach(Activity activity){

super.onAttach(activity);

try{

mListener =(OnArticleSelectedListener) activity;

}catch(ClassCastException e){

thrownewClassCastException(activity.toString()+" must implement OnArticleSelectedListener");

(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:

publicstaticclassFragmentAextendsListFragment{

OnArticleSelectedListener mListener;

...

@Override

publicvoid onListItemClick(ListView l,View v,int position,long id){

// Append the clicked item's row ID with the content provider Uri

Uri noteUri =ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);

// Send the event and Uri to the host activity mListener.onArticleSelected(noteUri);

}

... }

O parâmetro id passado para onListItemClick() é o ID da linha do item clicado, que a atividade (ou outro fragmento) utiliza para buscar o artigo a partir do aplicativo ContentProvider.

Adicionando itens à barra de ação

Seus fragmentos podem contribuir itens de menu para a atividade do menu de opções (e, conseqüentemente, a Barra de ação) pela execução onCreateOptionsMenu(). Para que esse método receba chamadas, no entanto, você deve chamar setHasOptionsMenu() durante onCreate(), para indicar que o fragmento gostaria de adicionar itens ao menu de opções (caso contrário, o fragmento não irá receber uma chamada para onCreateOptionsMenu()).

Os itens que você adicionar ao menu de opções do fragmento são acrescentados aos itens de menu existente. O fragmento também recebe callbacks para onOptionsItemSelected() quando um item de menu é selecionado.

(40)

Você também pode registrar uma exibição em seu layout para fornecer um menu de contexto, chamando registerForContextMenu(). Quando o usuário abre o menu de contexto, o fragmento recebe uma chamada para onCreateContextMenu(). Quando o usuário seleciona um item, o fragmento recebe uma chamada para onContextItemSelected().

Nota: Embora o fragmento receba um on-item-selected na chamada de retorno para

cada item de menu que acrescenta, a atividade é a primeira a receber o respectivo retorno quando o usuário seleciona um item de menu. Se a execução da atividade da chamada de retorno no item selecionado não lidar com o item selecionado, o evento é transmitido para retorno do fragmento. Isso é verdadeiro para o menu de opções e menus de contexto.

Manuseio do ciclo de vida do fragmento

(41)

Gerenciar o ciclo de vida de um fragmento é um pouco como gerir o ciclo de vida de uma atividade. Como uma atividade, um fragmento pode existir em três estados:

Retomado: O fragmento é visível na atividade de execução.

Em pausa: Outra atividade está em primeiro plano e tem o foco, mas a atividade em que

vive esse fragmento é ainda visível (a atividade do primeiro plano é parcialmente transparente ou não cobre a tela inteira).

Parado: O fragmento não é visível. A atividade host foi parada ou o fragmento foi

retirado da atividade, mas adicionado à volta da pilha. Um fragmento que parou ainda está vivo (todas as informações do estado e membro são mantidas pelo sistema). No entanto, já não é visível para o usuário e serão mortos se a atividade é morta.

Também como uma atividade, você pode manter o estado de um fragmento com um Bundle, no caso de a atividade do processo ser morta e você precisar restaurar o estado do fragmento, quando a atividade é recriada. Você pode salvar o estado durante o fragmento onSaveInstanceState() de callback e restaurá-lo durante onCreate(), onCreateView() ou onActivityCreated().

A diferença mais significativa no ciclo de vida entre uma atividade e um fragmento é como são armazenados em suas respectivas pilhas. Uma atividade é colocada em uma pilha de volta das atividades que é gerido pelo sistema quando ela está parada, por padrão (para que o usuário possa navegar de volta a ele com a chave de volta, como discutido em Tarefas e pilha de volta). No entanto, um fragmento é colocado em uma pilha de volta gerido pela atividade de acolhimento somente quando você solicitar explicitamente que a instância deve ser salva chamando addToBackStack() durante uma operação que remove o fragmento.

Gerenciar o ciclo de vida do fragmento é muito semelhante à gestão do ciclo de vida da atividade. Assim, as mesmas práticas de gestão do ciclo de vida de atividade também se aplicam aos fragmentos. O que você também precisa entender, porém, é como a vida da atividade afeta a vida do fragmento.

Coordenação com o ciclo de vida de atividade

O ciclo de vida da atividade em que o fragmento de vida afeta diretamente o ciclo de vida do fragmento, da mesma forma que cada ciclo de retorno para a atividade resulta

Referências

Documentos relacionados

O fabricante não vai aceitar nenhuma reclamação dos danos causados pela não observação deste manual ou por qualquer mudança não autorizada no aparelho.. Favor considerar

- Se o estagiário, ou alguém com contacto direto, tiver sintomas sugestivos de infeção respiratória (febre, tosse, expetoração e/ou falta de ar) NÃO DEVE frequentar

Local de realização da avaliação: Centro de Aperfeiçoamento dos Profissionais da Educação - EAPE , endereço : SGAS 907 - Brasília/DF. Estamos à disposição

É perceptível, desta forma, o constante aumento do aprofundamento dos personagens: os “príncipes” têm agora não só nome e falas, mas personalidades bem desenvolvidas,

A nutrição enteral (NE), segundo o Ministério da Saúde do Brasil, designa todo e qualquer “alimento para fins especiais, com ingestão controlada de nutrientes, na forma isolada

Os candidatos reclassificados deverão cumprir os mesmos procedimentos estabelecidos nos subitens 5.1.1, 5.1.1.1, e 5.1.2 deste Edital, no período de 15 e 16 de junho de 2021,

Nos tempos atuais, ao nos referirmos à profissão docente, ao ser professor, o que pensamos Uma profissão indesejada por muitos, social e economicamente desvalorizada Podemos dizer que

* Movement based refers to any Creative work, from any artistic area, using the movement as basis of work, research or critical approach. Movement understood as the movement of