SlideShare una empresa de Scribd logo
1 de 95
Google
Android




                     Jose Berardo
          Especializa Treinamentos
                                     1
Ementa
1. Introdução ao Android
2. Ambiente de desenvolvimento
3. Conceitos básicos
4. Application, Activities e Fragments
5. Intents e Broadcast Receivers
6. Views e Layout Managers
7. Persistência de dados e Content Providers
8. Shared Preferences


                                               2
Ementa
Application, Activities e Fragments
  Android Application
  Mais sobre o Manifest.xml
  Activities
     Pilhas, estados e ciclo de vida
     Monitoramento de estados e LogCat
     Activity subclasses
  Fragments
     Estratégias de fragments em tablets x smartphones
     Ciclo de vida
     Fragment subclasses e suporte a APIs antigas

                                                         3
O que faz uma aplicação?
Tipos de objetos que fazem uma aplicação Android:
  Activity
     Objetos de classes que herdem de
     android.app.Activity
     Controladora da interface de cada tela
     Activities carregam Views e Fragments
     para exibir conteúdo ao cliente
  Service
     Objetos do tipo android.app.Service
     Trabalhadores invisíveis que executam tarefas em background
     Atualizam Activities, disparam Notifications e difundem Intents
     Suas tarefas em geral são longas ou constantes sem nenhuma
     interação direta com o usuário

                                                                      4
O que faz uma aplicação?
Tipos de objetos que fazem uma aplicação Android:
  View
    Objetos de classes que herdem de
    android.view.View
    Representa cada componente na tela
    Gestores de layout herdam de sua subclasse
    abstrata android.view.ViewGroup
  Fragment
    Controladores de trechos de telas criados
    desde os primeiros tablets Android quando
    viram que uma Activity só para controlar
    essas telas maiores ficaria muito extensa
    São carregados por Activities, mas possuem
    seu próprio ciclo de vida


                                                    5
O que faz uma aplicação?
Tipos de objetos que fazem uma aplicação Android:
  Intent
    Objetos do tipo android.content.Intent
    Mecanismo de troca de mensagens interactivities e até mesmo
    interaplicações
    São extensamente usadas para abrir ou encerrar Activities ou
    Services, enviar mensagens em broadcast e muito mais
  Broadcast Receiver
    Intent listeners
    Fazem a aplicação reagir a determinadas Intents publicadas
    Constroem uma aplicação orientada a eventos



                                                                   6
O que faz uma aplicação?
Tipos de objetos que fazem uma aplicação Android:
  Notification
    Possibilitam que sua aplicação alerte o usuário de determinada
    ação sem interromper o que ele estiver fazendo no momento
    Publicam na barra de notificações, em geral a partir de um
    Service ou Broadcast Receiver
  Content Provider
    Objetos do tipo android.content.ContentProvider
    Mecanismo compartilhável de armazenamento de dados que interage
    com bancos SQL
    Há diversos content providers nativos que nos dão acesso a bases
    como lista de contatos e mídias armazenadas



                                                                       7
O que faz uma aplicação?
Tipos de objetos que fazem uma aplicação Android:
  Widget
    Componentes visuais que rodam direto na home screen
    São uma variação especial de Broadcast Receiver, permitindo
    interação com o usuário e execução direta
  Live Wallpaper
    Serviços com interatividade na home screen
    Widgets de fundos de tela responsivos




                                                                  8
Mais sobre o Manifest.xml
Outros atributos da tag raiz <manifest>
  package - determina o nome único do projeto. É
  recomendado que você utilize o padrão do DNS invertido
  finalizando com o nome do projeto
  android:* - prefixo XML que carrega nós definidos no
  namespace http://schemas.android.com/apk/res/android
  installLocation - Local default de instalação da aplicação.
  Disponível desde a API 8 (Froyo - 2.2)
    internalOnly - Só admite que a aplicação seja instalada na
    memória interna do dispositivo
    preferExternal - Sugere que a aplicação seja instalada no SD
    card. Se esta estiver cheia ou indisponível no momento da
    instalação, o sistema vai instalar na memória interna
    auto - Utiliza as definições padrão do cliente

                                                                   9
Mais sobre o Manifest.xml
Local de instalação da aplicação
  Instalar a app no SD card é bom por contar com mais espaço
  Mas quando o usuário utilizar o aparelho como USB mass
  storage, todas as apps instaladas no SD card serão encerradas
    Activities são fechadas
    Services são encerrados
    Alarmes são cancelados
    Widgets são removidos e Live Wallpapers são substituídos pelo
    default. Só voltam após o reinício da aplicação home. Em geral,
    quando ele reiniciar o aparelho
  A app não volta até a intervenção do usuário ou se estiver
  inscrita via BroadcastReceiver na Intent do sistema
  ACTION_EXTERNAL_APPLICATIONS_AVAILABLE

                                                                      10
Mais sobre o Manifest.xml
Apps que compartilham o mesmo usuário
  Cada app roda no Android em seu usuário único e seus
  recursos não são compartilhados para outros usuários
  O atributo sharedUserId pode ser usado para definir
  explicitamente uma string com o UID do usuário
    Duas apps podem definir o mesmo UID usando este atributo
    Têm acesso aos mesmos recursos como bases de dados
    Quando uma app chamar uma Activity de outra, esta segunda só
    rodará no mesmo processo (compartilhando até o que houver em
    memória) se tiver o mesmo sharedUserId
    As duas apps devem ter sido assinadas pelo mesmo certificado
  O atributo sharedUserString define um rótulo para o usuário


                                                                   11
Mais sobre o Manifest.xml
Tag <uses-configuration>
  Filtram sua aplicação para só funcionar se tais configurações
  estiverem presentes
    Notadamente úteis para games com jogabilidade única ou
    avançada
    reqTouchScreen - Restringe a determinado tipo de touchscreen
       undefined, notouch, stylus (requer touchscreen com suporte a caneta) e
       finger

    reqKeyboardType - Restringe a deteminado tipo de teclado
       undefined, nokeys, qwerty (exige um teclado padrão qwerty - com as
       letras q, w, e, r, t e y na primeira linha) e twelvekey (exige um teclado
       padrão de simples celulares - números, * e #)




                                                                                   12
Mais sobre o Manifest.xml
Tag <uses-configuration>
   reqHardKeyboard - Booleano. Exige ou não presença de
   teclado físico. Caso preciso de um tipo específico, determine
   também reqKeyboardType
   reqNavigation - Restringe à presença de determinado
   mecanismo de navegação
     undefined, nonav, dpad (diretional pad), trackball, wheel

   reqFiveWayNav - Booleano. Exige ou não que o dispositivo
   tenha recursos de navegação direcional como trackball ou dpad




                                                                   13
Mais sobre o Manifest.xml
Tags <uses-feature>
  Indica que sua aplicação só estará disponível se o hardware
  tiver determinada característica.
  Úteis para quando for imprescindível o uso de algum ou alguns
  recursos não disponíveis em todos os aparelhos
  O ideal é você nunca precisar citar nada aqui, mas caso
  necessite é bom restringir para evitar clientes frustrados
  O Google Play filtra a sua aplicação para só aparecer para
  quem estiver com hardware compatível com esta tag
  As características podem ser exigidas ou apenas
  recomendadas, mas todas as que precisarem de permissão
  do usuário são, por padrão, consideradas exigidas
    Para desligar esse filtro de exigência utilize o atributo
    required=“false”
                                                                  14
Mais sobre o Manifest.xml
Tags <uses-feature>
  Atributos:
    name - especifica qual o recurso que você precisa.
    Ex.: android.hardware.bluetooth
    Podem ser de hardware:
       Audio, bluetooth, camera, location, microphone, nfc, sensor, screen,
       telephony, television, touchscreen, usb, wifi

    Ou sofware:
       live_wallpaper e sip (voip)

  Você pode conferir a lista completa aqui:
    developer.android.com/guide/topics/manifest/uses-feature-
    element.html#features-reference


                                                                              15
Mais sobre o Manifest.xml
Tags <uses-feature>
  Atributos:
    required - determina se a característica é apenas uma boa
    indicação ou se chega a ser uma exigência
    glEsVersion - informa se há uma recomendação de versão do
    OpenGL ES (para gráficos). O valor é numérico de 32 bits
    expresso na base hexa, sendo os 16 primeiros reservados ao
    maior número da versão e os outros 16 ao menor número.
       glEsVersion=“0x00020001” - para a versão 2.1 (0002 -> 2 e 0001 ->1)

  Exemplos:
    <uses-feature android:name="android.hardware.camera"
                  android:required="false"/>
    <uses-feature android:glEsVersion="0x00020001"
                     android:required="true" />

                                                                             16
Mais sobre o Manifest.xml
Tags <uses-permission>
  Declara quais permissões a
  aplicação vai solicitar do usuário
  antes de ser instalada
     Basicamente, todas as
     operações que implicarem em
     custos ou questões de
     segurança precisam ser
     apresentadas ao cliente
Traz apenas o atributo name e a lista
possível nele é enorme




                                        17
Activity
 Principal classe para aplicativos que precisam da
 interação com o usuário
 Declaração mais básica de uma Activity no manifest
                                                        Só é
   <activity android:label="@string/app_name"   necessário .Classe por
     android:name=".MainActivity">              causa do package de
   </activity>                                      <manifest>

 Construção fundamental da classe
   public class MainActivity extends Activity {
     protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ...
     }
   }

                                                                         18
Pilhas de Activities
 As activities são organizadas em pilhas (Last in first out)
 O estado delas é determinado pela sua posição na pilha
   Quando uma activity inicia, ela fica ativa no topo da pilha,
   quando o usuário aciona o botão back, a activity logo abaixo na
   pilha se torna ativa.




                                                                     19
package br.com.especializa.minhaprimeiraapp;

import android.os.Bundle;                                                Código gerado
import android.app.Activity;                                            pelo Hello World
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


       A tarefa mais básica e comum do método onCreate é carregar alguma
       View através do método setContentView(). Ele vai instanciar os objetos
      Java referentes a cada tag desse layout e definir o que será exibido assim
                        que Activity chegar no modo Running


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}



                                                                                           20
Estados de uma Activity

           estados




métodos
callback




                           21
Estados de uma Activity
                     activity iniciada


                              métodos
           estados           chamados




métodos
callback




                                         21
Estados de uma Activity
                     activity iniciada


                              métodos
           estados           chamados
                      activity está
                         ativa




métodos
callback




                                         21
Estados de uma Activity
                     activity iniciada


                              métodos
           estados           chamados
                      activity está
                         ativa




                                             activity
métodos                                  está visível mas
callback                                    sem foco




                                                            21
Estados de uma Activity
                                         activity iniciada


                                                  métodos
           estados                               chamados
                                          activity está
                                             ativa




                      activity está na
                     memória mas não                             activity
métodos                                                      está visível mas
                        está visível
callback                                                        sem foco




                                                                                21
Estados de uma Activity
                                         activity iniciada


                                                  métodos
           estados                               chamados
                                          activity está
                                             ativa




                      activity está na
                     memória mas não                             activity
métodos                                                      está visível mas
                        está visível
callback                                                        sem foco




                                             activity está
                                             encerrada



                                                                                21
Pilhas de Activities
        Para garantir que as activities vão reagir às mudanças
        de estado, o Android provê uma série de métodos de
        callback manipuladores de eventos
            Visão geral de todos os métodos do ciclo de vida

                   activity                                            activity
            onRestoreIntanceState                                 onSaveIntanceState
                                                    activity                                activity
                                                  onResume                                 onPause
                                    activity                                                           activity
                                    onStart                                                            onStop
 activity                                                                                                          activity
oncreate                                                                                                          onDestroy
                                                                         activity
                                                                        onRestart



                                                                   Activity está ativa

                                                                   Activity está visível

                                               Tempo de vida completo da Activity
                                                                                                                              22
Métodos de ciclo de vida
onCreate(Bundle)
  Método principal onde
  normalmente as coisas
  são inicializadas
  Recebe um objeto
  bundle que empacota
  dados do estado anterior
  da Activity

onStart()
  Método chamado
  imediatamente antes da
  Activity ficar visível
  Seguido de onResume()
  ou onStop()
                             23
Métodos de ciclo de vida
onResume()
  Chamado imediatamente
  antes da activity estar
  pronta para interagir com
  o usuário
  É sempre seguido de
  onPause()

onPause()
  Método chamado no
  momento em que o
  sistema vai resumir outra
  Activity



                              24
Métodos de ciclo de vida
onStop()
  Chamado quando a
  activity não vai ficar mais
  visível
  Seguido de onRestart()
  se outra activity entrou
  na frente e saiu
  Seguido de onDestroy()
  se a activity for ser
  encerrada

onRestart()
  Chamado quando a
  activity for voltar a ficar
  visível, antes do onStart()
                                25
Métodos de ciclo de vida
onDestroy()
  Chamado quando a
  activity for encerrar
  O método isFinishing()
  retorna true aqui se a
  activity vai encerrar por
  que o usuário fechou ou
  a aplicação chamou o
  método finish()
  Retorna false se o
  sistema resolveu encerrar
  a activity para liberar
  espaço em memória



                              26
Logs do aplicativo
 A classe android.util.Log é útil para enviar informações
 no desenrolar do aplicativo
   Toda saída de sistema no Android (stdout e stderr) são
   direcionados para /dev/null, que significa que o bom e velho
   System.out.println() não vai funcionar
   O LogCat captura essas saídas de log e exibe as mensagens
   em cores diferentes:

              Código                    Nível            Cor
     Log.v("categoria", "texto");      Verbose          preto
     Log.d("categoria", "texto");       Debug            azul
     Log.i("categoria", "texto");        Info           verde
     Log.w("categoria", "texto");      Warning         laranja
     Log.e("categoria", "texto");        Error        vermelho
                                                                 27
package br.com.especializa.minhaprimeiraapp;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;

public class EstadosActivity extends Activity {

!   @Override
!   protected void onCreate(Bundle savedInstanceState) {
!   !   super.onCreate(savedInstanceState);
!   !   setContentView(R.layout.activity_estados);                 Exemplo de Logs para
!   !   Log.i("LOG DO APLICATIVO", "Passou pelo onCreate");
                                                                     monitoramento de
!   }
                                                                         estados
!   @Override
!   protected void onStart() {
!   !   super.onStart();
!   !   Log.i("LOG DO APLICATIVO", "Passou pelo onStart");
!   }

!   @Override
!   protected void onResume() {
!   !   super.onResume();
!   !   Log.i("LOG DO APLICATIVO", "Passou pelo onResume");
!   }

!   @Override
!   protected void onRestart() {
!   !   super.onRestart();
!   !   Log.i("LOG DO APLICATIVO", "Passou pelo onRestart");
!   }

!   // já deu pra entender né? Crie logs em todos os métodos citados anteriormente
}

                                                                                          28
LogCat maximizado - DDMS



        Assim que iniciamos o
              aplicativo




                                29
LogCat maximizado - DDMS



         Assim que iniciamos o
        Encerramos a aplicação
               aplicativo




                                 29
LogCat maximizado - DDMS


               Desligamos o visor
         Assim que iniciamos o
              (entrou a tela inicial),
        Encerramos a aplicação
              religamos e só então
                aplicativo
               encerramos a app




                                         29
Salvando estado da Activity
 Mesmo quando uma activity é pausada ou parada,
 seu estado é mantido em memória
 No entanto, o sistema pode destruir a activity para
 liberar memória, mesmo sem avisar ao usuário
   O sistema deverá ser capaz de recriar a activity de modo que
   retome seu estado original se o usuário quiser retornar a ela
   Existem métodos callback para lidar com as operação de
   registro de estado
     onSaveInstanceState - Chamado quando o sistema vai destruir
     a activity, mas sabe que precisa restaurar depois
        Quando o usuário clica em back, ele não é chamado

     onRestoreInstanceState - Logo antes do usuário solicitar
     novamente a activity destruída
                                                                   30
Salvando estado da activity




                              31
Salvando estado da activity
 Objeto Bundle
   Objeto que empacota um java.util.Map
     Delega todos os seus métodos (putInt(), putString(), getInt(),
     getString() ...)
   Passado aos métodos onSaveInstanceState(),
   onRestoreInstanceState() e mesmo o onCreate()
     Através dele podemos salvar dados em onSaveInstanceState() e
     recuperar esses dados em onRestoreInstanceState()




                                                                      32
!
    // Novos métodos em EstadosActivity



	   /**
!     * Método chamado quando o sistema resolver destruir
!     * a activity atual em situações onde precisar recuperá-la de volta
!     */
!   @Override
!   protected void onSaveInstanceState(Bundle outState) {
!   ! outState.putLong("momento", System.currentTimeMillis());
!   ! super.onSaveInstanceState(outState);
!   ! Log.i("LOG DO APLICATIVO", "Passou pelo onSaveInstanceState");
!   }
!
!   /**
!     * Método chamado quando o sistema recuperar uma activity
!     * destruída após chamada ao onSaveInstanceState
!     */
!   @Override
!   protected void onRestoreInstanceState(Bundle savedInstanceState) {
!   ! // TODO Auto-generated method stub
!   ! super.onRestoreInstanceState(savedInstanceState);
!   ! Log.i("LOG DO APLICATIVO", "Passou pelo onRestoreInstanceState " +
!   ! ! ! ! ! ! ! ! (System.currentTimeMillis() -
!   ! ! ! ! ! ! ! !              savedInstanceState.getLong("momento")) +
!   ! ! ! ! ! ! ! ! "ms depois do onSaveInstanceState");
!   }




                                                                            33
Salvando estado da activity


               Iniciamos a
               aplicação, o
          onRestoreInstanceState
             não foi chamado




                                   34
Salvando estado da activity


                   O visor
                Iniciamos a
            esmaeceu após um
               aplicação, o
                   tempo.
          onRestoreInstanceState
           onSaveInstanceState
             não foi chamado
               foi chamado




                                   34
Salvando estado da activity


             Desbloqueamos a tela
                       O visor
                    Iniciamos a
             reexibindo aapós um
              esmaeceu aplicação.
                   aplicação, o
          onRestoreInstanceState ainda
                       tempo.
            onRestoreInstanceState a
           não foi chamado porque
             onSaveInstanceState
              activityfoi chamado
                não não havia sido
                   foi chamado
                      destruída




                                         34
Salvando estado da activity


                   Clicamos no back
             Desbloqueamos a tela
                       O visor
                    Iniciamosaaaplicacão.
               para encerra
             reexibindo aapós um
              esmaeceu aplicação.
             Como a activityo
                   aplicação, não ainda
          onRestoreInstanceState é mais
                       tempo.
            onRestoreInstanceState a
                        necessária,
           não foi chamado porque
             onSaveInstanceState
              activityfoi chamado
                não não havia sido
                onSaveInstanceInstate
                   foi chamado
                    não foi chamado
                      destruída




                                            34
Salvando estado da activity


              Iniciamos a
       aplicação e rotacionamos visor noa tela
                           Desbloqueamos back
                                Clicamos
                                   O
                                Iniciamosaaaplicacão.
                            para encerra
      o aparelho. Esse éreexibindo aapós um
                           um caso aplicação.
                            esmaeceu
       em que o sistema Como a activityo
                                aplicação, não ainda
                      onRestoreInstanceState é mais
                           sempre  tempo.
                          onRestoreInstanceState a
                         não foi necessária,
         destrói e reconstrói achamado porque
                           onSaveInstanceState
                 activity activityfoi chamado
                             não não havia sido
                             onSaveInstanceInstate
                               foi chamado
                                não foi chamado
                                  destruída




                                                        34
Salvando estado da activity


         Curiosidade.        Iniciamos a
   Quando a tela esmaece, e rotacionamos visor noa tela
                      aplicação           Desbloqueamos back
                                               Clicamos
                                                  O
                                               Iniciamosaaaplicacão.
                                           para encerra
 a orientação da tela volta ao Esse éreexibindo aapós um
                     o aparelho.          um caso aplicação.
                                           esmaeceu
   estado inicial. Confiraque o sistema Como a activityo
                      em os                    aplicação, não ainda
                                     onRestoreInstanceState é mais
                                          sempre  tempo.
                                         onRestoreInstanceState a
                                        não foi necessária,
        métodos sendodestrói e reconstrói achamado porque
                                          onSaveInstanceState
          chamados              activity activityfoi chamado
                                            não não havia sido
                                            onSaveInstanceInstate
                                              foi chamado
                                               não foi chamado
                                                 destruída
                                Voltaremos a este
                               assunto na aula 6 ao
                               falarmos mais sobre
                                     interfaces




                                                                       34
Activity subclasses
Exemplos de subclasses:
  ListActivity - Activity que carrega
  ListViews para exibir coleções
  ExpandableListActivity - Activity
  que carrega ExpandableListViews
  TabActivity - Apresenta views em
  abas. Foi depreciada na API 13, em
  função dos fragments
  Aplicativos compilados com o extra Android Support Library
  poderão contar com FragmentActivity
    Trataremos deste assunto em Fragments
  Aplicativos compilados com a GoogleAPIs terão MapActivity
    Esse assunto será visto só em outro curso
                                                               35
ListActivity
 Classe que empacota um ListView sem precisarmos
 escrever nenhum arquivo de layout
 Exibe uma lista vertical de itens, quando não couberem
 na tela, carrega uma barra de rolagem
   É uma Activity com alguns métodos para gerenciamento de
   listas
 Para preencher a lista, passamos um objeto de uma
 classe que herde de ListAdapter
   Vamos trabalhar agora com ArrayAdapter e em assuntos
   posteriores com SimpleCursorAdapter



                                                             36
Activity subclasses
 Como não vamos criar uma
 view, vamos criar a Activity
 de outro jeito
   No Manifest, vá na aba
   Application e clique em add


   Mande criar uma Activity


   Em Attributes for Activity, clique
   em name para mandar gerar
   uma nova classe e preencha os
   demais atributos. É bem
   intuitivo.

                                        37
package br.com.especializa.minhaprimeiraapp;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

/**
  * Devemos herdar de ListActivity
  */
public class MinhaListaActivity extends ListActivity {
! @Override
! public void onCreate(Bundle savedInstanceState) {
!       super.onCreate(savedInstanceState);

!       // Valores que vão preencher a lista
!       String[] instrumentos = {"violão", "guitarra", "bateria", "gaita",
!       ! ! ! ! ! !         "microfone", "cajon", "bandolim", "congas",
!       ! ! ! ! ! !         "violino", "piano", "contra-baixo", "panela"};

!       // ArrayAdapter que vai saber fornecer cada item ao ListView
!       // context - this (toda Activity é um contexto)
!       // android.R.layout.simple_item_1 - componente visual de cada linha
!       // objetos - instrumentos - coleção de dados
!       ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
!       ! ! ! ! ! ! !             android.R.layout.simple_list_item_1,
!       ! ! ! ! ! ! !             instrumentos);

!       // Método que define o adapter do ListView
!       setListAdapter(adapter);
!   }

}

                                                                              38
package br.com.especializa.minhaprimeiraapp;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

/**
  * Devemos herdar de ListActivity
  */
public class MinhaListaActivity extends ListActivity {
! @Override
! public void onCreate(Bundle savedInstanceState) {
!       super.onCreate(savedInstanceState);

!       // Valores que vão preencher a lista
!       String[] instrumentos = {"violão", "guitarra", "bateria", "gaita",
!       ! ! ! Existe uma classe R padrão
                 ! ! !       "microfone", "cajon", "bandolim", "congas",
!       ! ! !do Android.! referencia todos
                 ! !     Ela "violino", "piano", "contra-baixo", "panela"};
               os componentes que podemos
!       // ArrayAdapter que vai saber fornecer cada item ao ListView
                        trabalhar
!       // context - this (toda Activity é um contexto)
!       // android.R.layout.simple_item_1 - componente visual de cada linha
!       // objetos - instrumentos - coleção de dados
!       ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
!       ! ! ! ! ! ! !             android.R.layout.simple_list_item_1,
!       ! ! ! ! ! ! !             instrumentos);

!       // Método que define o adapter do ListView
!       setListAdapter(adapter);
!   }

}

                                                                              38
package br.com.especializa.minhaprimeiraapp;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

/**
  * Devemos herdar de ListActivity
  */
public class MinhaListaActivity extends ListActivity {
! @Override
! public void onCreate(Bundle savedInstanceState) {
!       super.onCreate(savedInstanceState);

!       // Valores que vão preencher a lista
!       String[] instrumentos = {"violão", "guitarra", "bateria", "gaita",
!       ! ! ! Existe uma classe R padrão
                 ! ! !       "microfone", "cajon", "bandolim", "congas",
!       ! ! !do Android.! referencia todos
                 ! !     Ela "violino", "piano", "contra-baixo", "panela"};
               os componentes que podemos
!       // ArrayAdapter que vai saber fornecer cada item ao ListView
                        trabalhar
!       // context - this (toda Activity é um contexto)
!       // android.R.layout.simple_item_1 - componente visual de cada linha
!       // objetos - instrumentos - coleção de dados
!       ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
!       ! ! ! ! ! ! !             android.R.layout.simple_list_item_1,
!       ! ! ! ! ! ! !             instrumentos);

!       // Método que define o adapter do ListView
!       setListAdapter(adapter);
!   }

}

                                                                              38
ListAdapters
Como vimos, servem para realizar o bind entre uma
view e uma coleção de valores
ArrayAdapter
  Carrega coleções arrays ou Lists em telas ListView

CursorAdapter
  Listas maiores ou mais complexas precisam de um adapter
  mais inteligente do que o ArrayAdapter
  CursorAdapters unem cursores (objetos que gerenciam
  eficientemente coleções em buffers) e listviews
    Voltaremos a esse assunto quando fizermos consultas a bancos
    de dados


                                                                  39
Fragments
São porções de tela por baixo de uma Activity
  É possível combinar mais de um Fragment numa tela

Disponível desde a API 11 (Honeycomb)
  É possível decidir mostrar várias fragments em telas maiores
  (tablets) e continar usando navegação por activities (handsets)

Disponível para APIs mais antigas (a partir da 4) através
da Android Support Library
  No SDK Manager, vá aos extras e baixe esse pacote
  Seus próximos projetos já vão ser gerados com a inserção da
  dependência android-support-v4.jar


                                                                    40
Navegação em handsets
                        41
Navegação em tablets
                       42
?
Que tal começar por
   um exemplo
     do zero?


                      43
Exemplo de Fragments
1.Crie uma nova Activity
  1.1.Defina o nome FragmentsActivity.java. Por enquanto não
    vamos mudar o conteúdo padrão dela
  1.2.Renomeie a view gerada para fragment_dois_lados.xml

2.Crie mais duas views
  2.1.File > New > Other, depois Android > Android XML Layout File
  2.2.Nomes: fragment_esquerda.xml e fragment_direita.xml

3.Crie duas classes Java no pacote src
  3.1.FragmentEsquerda.java e FragmentDireita.java
  3.2.Elas devem herdar de android.support.v4.app.Fragment

                                                                     44
View principal do
   fragment_dois_lados.xml                     exemplo. Carrega um
                                                layout em linha com
                                                   dois elementos


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

! <fragment
! ! android:name="br.com.especializa.minhaprimeiraapp.FragmentEsquerda"
! ! android:id="@+id/fragmentEsquerda"
! ! android:layout_weight="1"
! ! android:layout_width="0px"
! ! android:layout_height="match_parent" />
! <fragment
! ! android:name="br.com.especializa.minhaprimeiraapp.FragmentDireita"
! ! android:id="@+id/fragmentDireita"
! ! android:layout_weight="1"
! ! android:layout_width="0px"                                         Tags
! ! android:layout_height="match_parent" />                      fragment indicam
</LinearLayout>
                                                                      no atributo name o
                                                                       nome da classe
                                                                         controladora



                                                                                           45
fragment_esquerda.xml
    Seu conteúdo é irrelevante
          no momento


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
! xmlns:android="http://schemas.android.com/apk/res/android"
! android:orientation="vertical"
! android:layout_width="fill_parent"
! android:layout_height="fill_parent"                        Mudamos a cor
! android:background="#00FF00">                           do background só pra
! <TextView                                                ficar destacar mais o
! ! android:layout_width="fill_parent"                           exemplo
! ! android:layout_height="wrap_content"
! ! android:text="Fragmento da esquerda"
! ! android:textColor="#000000"
! ! android:textSize="25sp" />

</LinearLayout>

                                                 fragment_direita.xml
                                                 Pode ter um conteúdo
                                                 semelhante. Só altere a
                                                     cor do fundo




                                                                                  46
package br.com.especializa.minhaprimeiraapp;

import   android.os.Bundle;                          Vamos herdar de
import   android.support.v4.app.Fragment;          Fragment da support
import   android.view.LayoutInflater;
                                                          API
import   android.view.View;
import   android.view.ViewGroup;

public class FragmentEsquerda extends Fragment {

!   @Override
!   public View onCreateView(LayoutInflater inflater, ViewGroup container,
!   ! ! Bundle savedInstanceState) {
!   ! // LayoutInflater é um objeto com a capacidade de ler um arquivo XML,
!   ! // criar os objetos Java referentes a cada componente escrito lá
!   ! // e exibi-lo em algum lugar.
!   ! // Até então nós só havíamos conseguido isso com o setContentView()
!   ! // do onCreate da Activity.
!   ! // Que por sua vez carrega sempre na tela como um todo
!   ! return inflater.inflate(R.layout.fragment_esquerda, container, false);
!   }

}
                                                                             No exemplo,
      Método callback do            Chamada que                          FragmentDireita.java
     momento em que a view       carrega a “sub” view                      deve ter a mesma
       principal for criada       referenciada em R                          composição




                                                                                                47
Como tudo aconteceu?
                         FragmentsActivity.java
               setContentView(R.layout.fragment_dois_lados)
                        Carregou a view principal


                        fragment_dois_lados.xml
                             Tags <fragment>
                  Cada tag carregou uma classe Fragment


   FragmentEsquerda.java                        FragmentDireita.java
         inflater.inflate()                           inflater.inflate()
Carregou fragment_esquerda.xml               Carregou fragment_direita.xml



   fragment_esquerda.xml                        fragment_direita.xml
   Simples arquivo de layout                   Simples arquivo de layout



                                                                             48
O que ganhamos com isso?
                                                            Telas maiores exibem
                                                             mais informações




                                                   Imagine
      A navegação não                        uma única Activity
      descarrega a tela                    para controlar todos os
          anterior                              seus eventos




 Cada Fragment            controla a sua                  porção de tela




                                                                                   49
No tablet, o resultado foi bom




                                 50
Mas no smartphone...




                       51
Fragments
Podemos detectar de alguma forma que a tela é
grande e só então exibir dois fragments
Se a tela for menor, exibiremos apenas um fragment
  Este fragment irá abrir outra Activity com o segundo fragment
  dentro
1. Crie um novo arquivo XML de layout
  1.1.Chame-o de fragment_um_lado.xml
2. Altere a Activity principal para escolher entre ele ou o de dois
   lados




                                                                      52
Um ou dois fragments

                FragmentsActivity.java
                         OU
                    setContentView


fragment_um_lado.xml            fragment_dois_lados.xml



FragmentEsquerda.java                FragmentDireita.java



fragment_esquerda.xml                fragment_direita.xml




                                                            53
fragment_um_lado.xml
     Apenas um fragment



<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
! android:name="br.com.especializa.minhaprimeiraapp.FragmentEsquerda"
! android:id="@+id/fragmentEsquerda"
! android:layout_width="match_parent"
! android:layout_height="match_parent" />




                                                                        54
1.    @Override
2.    protected void onCreate(Bundle savedInstanceState) {
3.        super.onCreate(savedInstanceState);
4.        boolean doisPaineis = false;
5.
6.         // Verificamos se a tela é padrão XLARGE
7.         if ((getResources().getConfiguration().screenLayout
8.                & Configuration.SCREENLAYOUT_SIZE_XLARGE)
9.         ! == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
10.
11.         ! Toast.makeText(this, "XLARGE", Toast.LENGTH_LONG).show();
12.         ! doisPaineis = true;
13.
14.        // Verificamos se a tela é padrão LARGE
15.        } else if ((getResources().getConfiguration().screenLayout &
16.               Configuration.SCREENLAYOUT_SIZE_LARGE)
17.         ! == Configuration.SCREENLAYOUT_SIZE_LARGE) {
18.
19.         ! Toast.makeText(this, "LARGE", Toast.LENGTH_LONG).show();
20.         ! doisPaineis = true;
21.
22.         }
23.
24.        if (doisPaineis) {
25.            setContentView(R.layout.fragment_dois_lados);
26.        } else {
27.            setContentView(R.layout.fragment_um_lado);
28.        }
29.    }




                                                                          55
Fragments
Nas linhas 7 e 15
  getResources() retornou o objeto Resources a partir do qual
  se obtém dados dos recursos do dispositivo
  getConfiguration() retornou dados da configuração corrente
  screenLayout trouxe uma máscara de bits sobre o tamanho
  da tela
  Perguntamos se a máscara de bits casa com o padrão
  XLARGE ou LARGE
  Nesses casos, e só nesses casos, doisPaineis virou true
  E chamamos fragments_dois_lados



                                                                56
Fragments
Como vamos exibir o layout fragment_direita.xml?
Ele deverá vir a partir de uma nova Activity
  Esta nova Activity não vai controlar a view do fragment
    Essa tarefa já ficou a cargo da classe DireitaFragment.java
1. Vamos criar um botão em fragment_esquerda.xml
2. Implementar o evento de clique no EsquerdaFragment.java
  2.1. Será feito no novo método callback onActivityCreate()
3. Criar a nova Activity chamada DireitaFragmentActivity.java




                                                                 57
Exemplo completo
                                Activity1             Activity2



                FragmentsActivity.java
                                                  FragmentDireitaActivity.java
                         OU
                    setContentView


fragment_um_lado.xml            fragment_dois_lados.xml
                                                                    FragmentManager
                                                                    FragmentTransaction

FragmentEsquerda.java                FragmentDireita.java



fragment_esquerda.xml                fragment_direita.xml

                                                                  click no botão
                                                                                          58
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
! xmlns:android="http://schemas.android.com/apk/res/android"
! android:orientation="vertical"
! android:layout_width="fill_parent"
! android:layout_height="fill_parent"
! android:background="#00FF00">
! <TextView
! ! android:layout_width="fill_parent"
! ! android:layout_height="wrap_content"
! ! android:text="Fragmento da esquerda"
! ! android:textColor="#000000"
                                                   Novo botão em
! ! android:textSize="25sp" />
                                               fragment_esquerda.xml
!   <Button
!       android:id="@+id/btnChamarDireita"
!       android:layout_width="wrap_content"
!       android:layout_height="wrap_content"
!       android:text="Chamar direita" />

</LinearLayout>




                                                                       59
Novo método em                                  getActivity() recupera a
   FragmentEsquerda.java                                Activity associada ao
                                                               Fragment

@Override
public void onActivityCreated(Bundle savedInstanceState) {
! super.onActivityCreated(savedInstanceState);
!
! Button b = (Button) getActivity().findViewById(R.id.btnChamarDireita);
! b.setOnClickListener(new View.OnClickListener() {
! !
! ! @Override
! ! public void onClick(View v) {
! ! ! if (getActivity().findViewById(R.id.fragmentDireita) == null) {
! ! ! ! Intent i = new Intent(getActivity(), FragmentDireitaActivity.class);
! ! ! ! getActivity().startActivity(i);
! ! ! }
! ! }
! });
!
}               A chamada à próxima
            Activity precisa da criação de
            Intents. Assunto da próxima
                          aula




                                                                                  60
package br.com.especializa.minhaprimeiraapp;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;

public class FragmentDireitaActivity extends FragmentActivity {

!   @Override
!   protected void onCreate(Bundle savedInstanceState) {
!   ! super.onCreate(savedInstanceState);                                  Novo objeto em
!   ! Fragment fragment = new FragmentDireita();                     FragmentDireita que vai
                                                                   controlar a view. O papel desta
!   !   getSupportFragmentManager().beginTransaction()                Activity é apenas criá-lo
!   !   .add(android.R.id.content, fragment).commit();
!   !
!   }
}


    - getSupportFragmentManager() retorna o objeto FragmentManager.
    - Seu método beginTransation() é quem adiciona, remove ou substitui
      fragments ao layout da Activity atual
    - android.R.id.content referencia a raiz de elementos da View
    - commit() realiza a operação




                                                                                                     61
O ciclo de vida do Fragment
é parecido e vinculado ao de
uma Activity
  Se a Activity parar, seus
  fragments também param. Se for
  destruída, eles também serão
  onAttach(Activity)
    Chamado assim que o fragment
    for anexado a uma Activity.
    Ela é passada como parâmetro
  onCreate(Bundle)
    Semelhante ao da Activity. É
    chamado para fazer suas
    inicializações




                                   62
onCreateView(LayoutInflater,
ViewGroup, Bundle)
  O método mais usado em um
  Fragment representa o momento
  exato em que ele cria sua
  interface com o usuário
  Recebe o inflater que vai
  carregar a view, o ViewGroup
  que servirá de container e o
  mesmo bundle do onCreate
onActivityCreated(Bundle)
  Chamado logo depois da Activity
  ser criada
  Como Fragments não herdam
  de Context, precisam sempre
  chamar a Activity para conseguir
  realizar algumas operações de
  conteúdo
     Lembra do Toast, por exemplo?
     A partir daqui getActivity() não
     retorna nulo
                                        63
onStart()
  Chamado logo quando o
  Fragment estiver visível
onResume()
  Chamado logo quando ele
  assumir interatividade com o
  usuário
onPause()
  Chamado assim que ele perder
  a interatividade
onStop()
  Chamado assim que a Activity
  não estiver mais visível




                                 64
onDestroyView(LayoutInflater,
ViewGroup, Bundle)
  Método parecido com o
  onCreateView()
  Roda no momento em que a
  view carregada nele for destruída
onDestroy()
  Roda assim que o fragment não
  tiver mais serventia
onDetach()
  Roda quando não estiver mais
  anexado a uma Activity




                                      65
Fragment subclasses
Há duas versões de Fragments
  Elas possuem estruturas hierárquicas diferentes
  android.app.Fragment
    Classe adicionada na API 11 (honeycomb) justamente no
    momento da ascensão dos tablets
    Herdada por DialogFragment, ListFragment, PreferenceFragment
    e WebViewFragment
  android.support.v4.app.Fragment
    Classe da API Android Suppor V4, que é o extra que porta os
    fragments lá pra trás na API 4 (Donut - 1.6)
    Herdada apenas por DialogFragment e ListFragment
       sendo as respectivas classes criadas neste mesmo pacote
       Não são as mesmas do pacote principal
                                                                   66
Suporte a APIs antigas
Apps com Fragments compatíveis com APIs antigas:
  Os fragments devem ser android.support.v4.app.Fragment
  As activities que anexam fragments devem herdar de
  android.support.v4.app.FragmentActivity
    Nelas, o objeto FragmentManager deve ser o do pacote
    android.support.v4.app, chamado exclusivamente por
    getSupportFragmentManager(), um método com função
    semelhante ao getFragmentManager()
    ListFragments e DialogFragments só podem ser do mesmo
    pacote da API de suporte

APIs v7 e v13
  São supersets da v4 e trazem mais coisas, mas requerem
  minSdkVersion 7 e 13 respectivamente

                                                            67
?
 Vamos analisar o
código gerado pelo
MasterDetailFlow


                     68
Esta foi a Activity
                                                                   principal

<!-- Trecho no AndroidManifest.xml referente
     ao MasterDetailFlow que criamos -->
<activity
    android:name="br.com.especializa.minhaprimeiraapp.ProdutoListActivity"
    android:label="@string/title_produto_list" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />            A segunda Activity
        <category android:name="android.intent.category.LAUNCHER" /> para quando a tela for
    </intent-filter>                                                            menor
</activity>
<activity
    android:name="br.com.especializa.minhaprimeiraapp.ProdutoDetailActivity"
    android:label="@string/title_produto_detail"
    android:parentActivityName=".ProdutoListActivity" >
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".ProdutoListActivity" />                 Atributo criado no Jelly
</activity>                                                        Bean 4.1 (API 16)



                                        Versão anterior à da
                                       API 16 para a mesma
                                               idéia



                                                                                             69
Navegação Up
A API 11 trouxe também as ActionBars e com elas, o
chamado Up button
As declarações do AndroidManifest definiram a Activity
a ser chamada quando este botão for acionado
  <meta name="android.support.PARENT_ACTIVITY">
    Para APIs anteriores à 16
  android:parentActivityName=""
    Para versões posteriores




                                                        70
Navegação Up e Back

                      Up button disponível
                       em telas internas




     Back button de
        sempre


                                             71
package br.com.especializa.minhaprimeiraapp;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class ProdutoListActivity extends FragmentActivity implements
                                                                             Interface
!   !  ProdutoListFragment.Callbacks {                                  criada pelo próprio
                                                                              exemplo
!   private boolean mTwoPane;

!   @Override
!   protected void onCreate(Bundle savedInstanceState) {
!   !   super.onCreate(savedInstanceState);
!   !   // Layout que só carrega um único Fragment
!   !   // Vai ser trocado por outro usando um técnica bem legal
!   !   setContentView(R.layout.activity_produto_list);

!   !   // De cara, parace que nunca vai entrar nesse if
!   !   if (findViewById(R.id.produto_detail_container) != null) {
!   !   !   // Se entrar, essa variável vira true
!   !   !   mTwoPane = true;
                                                                         O estilo
                                                                       do ícone vai
!   !   !   ((ProdutoListFragment) getSupportFragmentManager()         permanecer
!   !   !   !   !  .findFragmentById(R.id.produto_list))                 clicado
!   !   !   !   !  .setActivateOnItemClick(true);
!   !   }

!   }

!   // continua ...




                                                                                              72
!



    // Método que a interface criada exigiu que fosse implementado
    // O fragment controlador da lista vai invocá-lo de volta (Callback)
!    @Override
!    public void onItemSelected(String id) {
!    !   if (mTwoPane) {
!    !   !   // Em tela dupla (tablets), vamos criar um Bundle
             // para armazenar o id do produto clicado
!    !   !   Bundle arguments = new Bundle();
!    !   !   arguments.putString(ProdutoDetailFragment.ARG_ITEM_ID, id);
!    !   !   ProdutoDetailFragment fragment = new ProdutoDetailFragment();
!    !   !   fragment.setArguments(arguments); // Método que registra o bundle no Fragment

            // Substituindo o fragment de detalhes que estiver carregado por outro atualizado
!   !   !   getSupportFragmentManager().beginTransaction()
!   !   !   !   !   .replace(R.id.produto_detail_container, fragment).commit();

!   !   } else {
!   !   !   // Em telas simples, haverá uma chamada à nova Activity que vai
!   !   !   // receber no pacote o id do produto clicado
            // ... calma que ainda veremos Intents
!   !   !   Intent detailIntent = new Intent(this, ProdutoDetailActivity.class);
!   !   !   detailIntent.putExtra(ProdutoDetailFragment.ARG_ITEM_ID, id);
!   !   !   startActivity(detailIntent);
!   !   }
!   }
}




                                                                                                73
activity_produto_list.xml
            Apenas um fragment
                    gerado


<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/produto_list"
    android:name="br.com.especializa.minhaprimeiraapp.ProdutoListFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    tools:context=".ProdutoListActivity"
    tools:layout="@android:layout/list_content" />
                                                              Tablets, que possuem
                                                           telas grandes e APIs >= 11,
                                                         vão sobrescrever a referência de
<resources>                                                R ao layout de um fragment
    <item name="activity_produto_list" type="layout">              pelo de dois
       @layout/activity_produto_twopane
    </item>
</resources>


                     refs.xml em values-large                       Fez sentido o if
                       (nomenclatura antiga) e                      (mTwoPane) da
                      values-sw600dp (nova)                            Activity?

                                                                                            74
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:divider="?android:attr/dividerHorizontal"
    android:orientation="horizontal"
    android:showDividers="middle"
    tools:context=".ProdutoListActivity" >

    <fragment
        android:id="@+id/produto_list"
        android:name="br.com.especializa.minhaprimeiraapp.ProdutoListFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        tools:layout="@android:layout/list_content" />
                                                            activity_produto_twopane.xml
    <FrameLayout
        android:id="@+id/produto_detail_container"            carregando um fragment
        android:layout_width="0dp"                       produto_list e um outro componente
        android:layout_height="match_parent"                  produto_detail_container
        android:layout_weight="3" />

</LinearLayout>




                                                                                              75
ListFragment da
                                                                  API de suporte
public class ProdutoListFragment extends ListFragment {

!   private static final String STATE_ACTIVATED_POSITION = "activated_position";
!   private Callbacks mCallbacks = sDummyCallbacks;
!   private int mActivatedPosition = ListView.INVALID_POSITION;
                                                                       Representa
!   /**                                                             posição inválida do
!     * Interface interna que a Activity principal implementou        toque no item
!     */
!   public interface Callbacks {
!   ! /**
!   !    * Método implementado pela Activity principal
!   !    */
!   ! public void onItemSelected(String id);
!   }

!   @Override
                                                                    Lembra do
!   public void onCreate(Bundle savedInstanceState) {
!   ! super.onCreate(savedInstanceState);                          ArrayAdapter?

!   !   // TODO: replace with a real list adapter.
!   !   setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(getActivity(),
!   !   ! ! android.R.layout.simple_list_item_activated_1,
!   !   ! ! android.R.id.text1, DummyContent.ITEMS));
!   }

    // continua ...


                                                                                          76
Assim que a
                                  view for criada. Ela é
                                      recriada em
                                        rotações
!    @Override
!    public void onViewCreated(View view, Bundle savedInstanceState) {
!    ! super.onViewCreated(view, savedInstanceState);

!    !   //   Recuperando um possível valor de item selecionado
!    !   if   (savedInstanceState != null
!    !   !    ! && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
!    !   !    setActivatedPosition(savedInstanceState
!    !   !    ! ! .getInt(STATE_ACTIVATED_POSITION));
!    !   }
!    }
                                                               Frescurinha
!    @Override                                             particular do código
!    public void onAttach(Activity activity) {                    gerado
!    ! super.onAttach(activity);

!    !   //   Activities containing this fragment must implement its callbacks.
!    !   if   (!(activity instanceof Callbacks)) {
!    !   !    throw new IllegalStateException(
!    !   !    ! ! "Activity must implement fragment's callbacks.");
!    !   }

!    !   mCallbacks = (Callbacks) activity;
!    }

    // Continua ...



                                                                                  77
!   @Override                                                   Quando o item for
!   public void onDetach() {
!   ! super.onDetach();                                       selecionado, chama o
!   ! mCallbacks = sDummyCallbacks;                            callback da activity
!   }

!   @Override
!   public void onListItemClick(ListView listView, View view, int position,
!   ! ! long id) {
!   ! super.onListItemClick(listView, view, position, id);
!   ! mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
!   }

!   @Override
!   public void onSaveInstanceState(Bundle outState) {
!   ! super.onSaveInstanceState(outState);
!   ! if (mActivatedPosition != ListView.INVALID_POSITION) {
!   ! ! // Serialize and persist the activated item position.
!   ! ! outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
!   ! }
!   }

    // Continua ...
                                      Salvando o item
                                       selecionado




                                                                                      78
!   public void setActivateOnItemClick(boolean activateOnItemClick) {
!   ! // When setting CHOICE_MODE_SINGLE, ListView will automatically
!   ! // give items the 'activated' state when touched.
!   ! getListView().setChoiceMode(                                      Redefinição
!   ! ! ! activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
!   ! ! ! ! ! : ListView.CHOICE_MODE_NONE);                       inusitada de métodos
!   }                                                             sobre a marcação de
                                                                     itens selecionados
!   private void setActivatedPosition(int position) {
!   ! if (position == ListView.INVALID_POSITION) {
!   ! ! getListView().setItemChecked(mActivatedPosition, false);
!   ! } else {
!   ! ! getListView().setItemChecked(position, true);
!   ! }

!   !   mActivatedPosition = position;
!   }
}




                                                                                          79
/**
 * Activity de detalhes para hansets
 */
public class ProdutoDetailActivity extends FragmentActivity {

!   @Override                                                             Carregou a view
!   protected void onCreate(Bundle savedInstanceState) {
!   !   super.onCreate(savedInstanceState);                            porque não houve um
!   !   setContentView(R.layout.activity_produto_detail);              fragment da direita no
                                                                             exemplo
!   !   // Exibindo o Up button
!   !   getActionBar().setDisplayHomeAsUpEnabled(true);

!   !   if (savedInstanceState == null) {
!   !   !   // Criando o fragment da direita
!   !   !   Bundle arguments = new Bundle();
!   !   !   arguments.putString(ProdutoDetailFragment.ARG_ITEM_ID, getIntent()
!   !   !   !   !  .getStringExtra(ProdutoDetailFragment.ARG_ITEM_ID));
!   !   !   ProdutoDetailFragment fragment = new ProdutoDetailFragment();
!   !   !   fragment.setArguments(arguments);
!   !   !   getSupportFragmentManager().beginTransaction()
!   !   !   !   !  .add(R.id.produto_detail_container, fragment).commit();
!   !   }
!   }

!   @Override
!   public boolean onOptionsItemSelected(MenuItem item) {           Callback do evento
!   !   switch (item.getItemId()) {                                 de clique no botão
!   !   case android.R.id.home:                                     options do Android
!   !   !   NavUtils.navigateUpTo(this, new Intent(this,
!   !   !   !   !  ProdutoListActivity.class));
!   !   !   return true;
!   !   }
!   !   return super.onOptionsItemSelected(item);
!   }
}
                                                                                                80
?
Que tal fazer um
 ListFragment
   do zero?


                   81

Más contenido relacionado

La actualidad más candente

Iniciando o Desenvolvimento para o Google Android
Iniciando o Desenvolvimento para o Google AndroidIniciando o Desenvolvimento para o Google Android
Iniciando o Desenvolvimento para o Google AndroidSalvador Torres
 
Curso de Android - aula 3
Curso de Android - aula 3Curso de Android - aula 3
Curso de Android - aula 3Jose Berardo
 
Desenvolvimento de Apps e Games para Android - Parte 1
Desenvolvimento de Apps e Games para Android - Parte 1Desenvolvimento de Apps e Games para Android - Parte 1
Desenvolvimento de Apps e Games para Android - Parte 1Erisvaldo Junior
 
Tutorial - Como criar sua primeira app para Android
Tutorial - Como criar sua primeira app para AndroidTutorial - Como criar sua primeira app para Android
Tutorial - Como criar sua primeira app para AndroidSidney Roberto
 
Entenda porque seu aplicativo de Android não deve ser igual ao de iPhone
Entenda porque seu aplicativo de Android não deve ser igual ao de iPhoneEntenda porque seu aplicativo de Android não deve ser igual ao de iPhone
Entenda porque seu aplicativo de Android não deve ser igual ao de iPhoneHenrique Perticarati
 
Curso de Android - aula 2
Curso de Android - aula 2Curso de Android - aula 2
Curso de Android - aula 2Jose Berardo
 
Desenvolvendo aplicações em Java para o Google Android - Ranieri de Souza Fer...
Desenvolvendo aplicações em Java para o Google Android - Ranieri de Souza Fer...Desenvolvendo aplicações em Java para o Google Android - Ranieri de Souza Fer...
Desenvolvendo aplicações em Java para o Google Android - Ranieri de Souza Fer...Tchelinux
 
Programando Android - Aula 1
Programando Android - Aula 1Programando Android - Aula 1
Programando Android - Aula 1Kalil Maciel
 
SESTINFO 2011 Apresentacao Android
SESTINFO 2011 Apresentacao AndroidSESTINFO 2011 Apresentacao Android
SESTINFO 2011 Apresentacao AndroidRafael Sakurai
 
Apostila passo a passo como programar em android edição03
Apostila passo a passo como programar em android edição03Apostila passo a passo como programar em android edição03
Apostila passo a passo como programar em android edição03Horacio Diamante Mondlane
 
Introdução à plataforma Android
Introdução à plataforma AndroidIntrodução à plataforma Android
Introdução à plataforma AndroidNatanael Fonseca
 
PALESTRA :: Desenvolvimento para plataforma Android
PALESTRA :: Desenvolvimento para plataforma Android PALESTRA :: Desenvolvimento para plataforma Android
PALESTRA :: Desenvolvimento para plataforma Android Fundação Vanzolini
 
Capítulo 01 - Fundamentos de Android e o HelloWorld
Capítulo 01 - Fundamentos de Android e o HelloWorldCapítulo 01 - Fundamentos de Android e o HelloWorld
Capítulo 01 - Fundamentos de Android e o HelloWorldMarcio Palheta
 

La actualidad más candente (20)

Iniciando o Desenvolvimento para o Google Android
Iniciando o Desenvolvimento para o Google AndroidIniciando o Desenvolvimento para o Google Android
Iniciando o Desenvolvimento para o Google Android
 
Curso de Android - aula 3
Curso de Android - aula 3Curso de Android - aula 3
Curso de Android - aula 3
 
Desenvolvimento de Apps e Games para Android - Parte 1
Desenvolvimento de Apps e Games para Android - Parte 1Desenvolvimento de Apps e Games para Android - Parte 1
Desenvolvimento de Apps e Games para Android - Parte 1
 
Android Aula 5
Android Aula 5Android Aula 5
Android Aula 5
 
Tutorial - Como criar sua primeira app para Android
Tutorial - Como criar sua primeira app para AndroidTutorial - Como criar sua primeira app para Android
Tutorial - Como criar sua primeira app para Android
 
Introdução ao Android Studio
Introdução ao Android StudioIntrodução ao Android Studio
Introdução ao Android Studio
 
Entenda porque seu aplicativo de Android não deve ser igual ao de iPhone
Entenda porque seu aplicativo de Android não deve ser igual ao de iPhoneEntenda porque seu aplicativo de Android não deve ser igual ao de iPhone
Entenda porque seu aplicativo de Android não deve ser igual ao de iPhone
 
Curso de Android - aula 2
Curso de Android - aula 2Curso de Android - aula 2
Curso de Android - aula 2
 
Desenvolvendo aplicações em Java para o Google Android - Ranieri de Souza Fer...
Desenvolvendo aplicações em Java para o Google Android - Ranieri de Souza Fer...Desenvolvendo aplicações em Java para o Google Android - Ranieri de Souza Fer...
Desenvolvendo aplicações em Java para o Google Android - Ranieri de Souza Fer...
 
Programando Android - Aula 1
Programando Android - Aula 1Programando Android - Aula 1
Programando Android - Aula 1
 
SESTINFO 2011 Apresentacao Android
SESTINFO 2011 Apresentacao AndroidSESTINFO 2011 Apresentacao Android
SESTINFO 2011 Apresentacao Android
 
Android Aprendiz
Android AprendizAndroid Aprendiz
Android Aprendiz
 
Apostila passo a passo como programar em android edição03
Apostila passo a passo como programar em android edição03Apostila passo a passo como programar em android edição03
Apostila passo a passo como programar em android edição03
 
Android
AndroidAndroid
Android
 
Introdução à plataforma Android
Introdução à plataforma AndroidIntrodução à plataforma Android
Introdução à plataforma Android
 
PALESTRA :: Desenvolvimento para plataforma Android
PALESTRA :: Desenvolvimento para plataforma Android PALESTRA :: Desenvolvimento para plataforma Android
PALESTRA :: Desenvolvimento para plataforma Android
 
Plataforma Android
Plataforma AndroidPlataforma Android
Plataforma Android
 
Capítulo 01 - Fundamentos de Android e o HelloWorld
Capítulo 01 - Fundamentos de Android e o HelloWorldCapítulo 01 - Fundamentos de Android e o HelloWorld
Capítulo 01 - Fundamentos de Android e o HelloWorld
 
Android
Android Android
Android
 
Android
AndroidAndroid
Android
 

Similar a Curso de Android Aula 4

Introdução ao android
Introdução ao androidIntrodução ao android
Introdução ao androidPaulo Remoli
 
Desenvolvendo para Android
Desenvolvendo para AndroidDesenvolvendo para Android
Desenvolvendo para AndroidClaudio Pereira
 
Desenvolvimento android
Desenvolvimento androidDesenvolvimento android
Desenvolvimento androidDiego Keller
 
Android Palestra
Android PalestraAndroid Palestra
Android PalestraRenato
 
Minicurso Android Ronildo Oliveira
Minicurso Android  Ronildo OliveiraMinicurso Android  Ronildo Oliveira
Minicurso Android Ronildo OliveiraRonildo Oliveira
 
Introdução a Plataforma Android
Introdução a Plataforma AndroidIntrodução a Plataforma Android
Introdução a Plataforma AndroidÉdipo Souza
 
Aula01 - introdução, Activity
Aula01 - introdução,  ActivityAula01 - introdução,  Activity
Aula01 - introdução, ActivityArthur Emanuel
 
Minicurso de Android
Minicurso de AndroidMinicurso de Android
Minicurso de AndroidEdgar Eler
 
Desenvolvendo Soluções com Android
Desenvolvendo Soluções com AndroidDesenvolvendo Soluções com Android
Desenvolvendo Soluções com Androidjgbirk
 
Computação Móvel 2012.2 - Android
Computação Móvel 2012.2 - AndroidComputação Móvel 2012.2 - Android
Computação Móvel 2012.2 - AndroidTiago Bencardino
 
Introdução ao android e plataforma android
Introdução ao android e plataforma androidIntrodução ao android e plataforma android
Introdução ao android e plataforma androidJuarez Junior
 
Treinamento básico de Android
Treinamento básico de AndroidTreinamento básico de Android
Treinamento básico de AndroidTiago Barreto
 
Minicurso de Desenvolvimento Android - Iguatu - CE
Minicurso de Desenvolvimento Android - Iguatu - CEMinicurso de Desenvolvimento Android - Iguatu - CE
Minicurso de Desenvolvimento Android - Iguatu - CERonildo Oliveira
 

Similar a Curso de Android Aula 4 (20)

Introdução ao android
Introdução ao androidIntrodução ao android
Introdução ao android
 
Apostilaandroidfatecnormal
ApostilaandroidfatecnormalApostilaandroidfatecnormal
Apostilaandroidfatecnormal
 
Desenvolvendo para Android
Desenvolvendo para AndroidDesenvolvendo para Android
Desenvolvendo para Android
 
Desenvolvimento android
Desenvolvimento androidDesenvolvimento android
Desenvolvimento android
 
Android Palestra
Android PalestraAndroid Palestra
Android Palestra
 
Minicurso Android Ronildo Oliveira
Minicurso Android  Ronildo OliveiraMinicurso Android  Ronildo Oliveira
Minicurso Android Ronildo Oliveira
 
Android - Notas de aula
Android - Notas de aulaAndroid - Notas de aula
Android - Notas de aula
 
Introdução a Plataforma Android
Introdução a Plataforma AndroidIntrodução a Plataforma Android
Introdução a Plataforma Android
 
Aula01 - introdução, Activity
Aula01 - introdução,  ActivityAula01 - introdução,  Activity
Aula01 - introdução, Activity
 
Android User Interface
Android User InterfaceAndroid User Interface
Android User Interface
 
Introdução ao Android
Introdução ao AndroidIntrodução ao Android
Introdução ao Android
 
Minicurso de Android
Minicurso de AndroidMinicurso de Android
Minicurso de Android
 
Desenvolvendo Soluções com Android
Desenvolvendo Soluções com AndroidDesenvolvendo Soluções com Android
Desenvolvendo Soluções com Android
 
Android
AndroidAndroid
Android
 
Computação Móvel 2012.2 - Android
Computação Móvel 2012.2 - AndroidComputação Móvel 2012.2 - Android
Computação Móvel 2012.2 - Android
 
Empreendedori$mo com Android
Empreendedori$mo com AndroidEmpreendedori$mo com Android
Empreendedori$mo com Android
 
O futuro do Android
O futuro do AndroidO futuro do Android
O futuro do Android
 
Introdução ao android e plataforma android
Introdução ao android e plataforma androidIntrodução ao android e plataforma android
Introdução ao android e plataforma android
 
Treinamento básico de Android
Treinamento básico de AndroidTreinamento básico de Android
Treinamento básico de Android
 
Minicurso de Desenvolvimento Android - Iguatu - CE
Minicurso de Desenvolvimento Android - Iguatu - CEMinicurso de Desenvolvimento Android - Iguatu - CE
Minicurso de Desenvolvimento Android - Iguatu - CE
 

Más de Jose Berardo

HTML5 Mobile - Aula 3 - Device Orientation
HTML5 Mobile - Aula 3 - Device OrientationHTML5 Mobile - Aula 3 - Device Orientation
HTML5 Mobile - Aula 3 - Device OrientationJose Berardo
 
Oracle Certified Associate - Java Programmer I - aula 2
Oracle Certified Associate - Java Programmer I - aula 2Oracle Certified Associate - Java Programmer I - aula 2
Oracle Certified Associate - Java Programmer I - aula 2Jose Berardo
 
HTML5 Mobile Aula 1
HTML5 Mobile Aula 1HTML5 Mobile Aula 1
HTML5 Mobile Aula 1Jose Berardo
 
Java Certified Associate Aula 1
Java Certified Associate Aula 1Java Certified Associate Aula 1
Java Certified Associate Aula 1Jose Berardo
 
Curso de Java EE 6
Curso de Java EE 6Curso de Java EE 6
Curso de Java EE 6Jose Berardo
 
Html5 - O futuro da Web
Html5 - O futuro da WebHtml5 - O futuro da Web
Html5 - O futuro da WebJose Berardo
 
O que há de novo no PHP 5.3
O que há de novo no PHP 5.3O que há de novo no PHP 5.3
O que há de novo no PHP 5.3Jose Berardo
 
Certificacoes Desenvolvedores
Certificacoes DesenvolvedoresCertificacoes Desenvolvedores
Certificacoes DesenvolvedoresJose Berardo
 

Más de Jose Berardo (15)

Html5 Aula 6
Html5 Aula 6Html5 Aula 6
Html5 Aula 6
 
Html5 Aula 5
Html5 Aula 5Html5 Aula 5
Html5 Aula 5
 
Html5 Aula 4
Html5 Aula 4Html5 Aula 4
Html5 Aula 4
 
HTML5 Mobile - Aula 3 - Device Orientation
HTML5 Mobile - Aula 3 - Device OrientationHTML5 Mobile - Aula 3 - Device Orientation
HTML5 Mobile - Aula 3 - Device Orientation
 
Oracle Certified Associate - Java Programmer I - aula 2
Oracle Certified Associate - Java Programmer I - aula 2Oracle Certified Associate - Java Programmer I - aula 2
Oracle Certified Associate - Java Programmer I - aula 2
 
HTML5 Mobile Aula 1
HTML5 Mobile Aula 1HTML5 Mobile Aula 1
HTML5 Mobile Aula 1
 
Java Certified Associate Aula 1
Java Certified Associate Aula 1Java Certified Associate Aula 1
Java Certified Associate Aula 1
 
Curso de Java EE 6
Curso de Java EE 6Curso de Java EE 6
Curso de Java EE 6
 
Html5 Aula 3
Html5 Aula 3Html5 Aula 3
Html5 Aula 3
 
Html5 aula 02
Html5 aula 02Html5 aula 02
Html5 aula 02
 
Html5 aula 01
Html5 aula 01Html5 aula 01
Html5 aula 01
 
Html5 - O futuro da Web
Html5 - O futuro da WebHtml5 - O futuro da Web
Html5 - O futuro da Web
 
O que há de novo no PHP 5.3
O que há de novo no PHP 5.3O que há de novo no PHP 5.3
O que há de novo no PHP 5.3
 
Certificacao Php
Certificacao PhpCertificacao Php
Certificacao Php
 
Certificacoes Desenvolvedores
Certificacoes DesenvolvedoresCertificacoes Desenvolvedores
Certificacoes Desenvolvedores
 

Último

ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docxATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx2m Assessoria
 
Luís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdfLuís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdfLuisKitota
 
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docxATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx2m Assessoria
 
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docxATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx2m Assessoria
 
Programação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdfProgramação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdfSamaraLunas
 
ATIVIDADE 1 - SISTEMAS DISTRIBUÍDOS E REDES - 52_2024.docx
ATIVIDADE 1 - SISTEMAS DISTRIBUÍDOS E REDES - 52_2024.docxATIVIDADE 1 - SISTEMAS DISTRIBUÍDOS E REDES - 52_2024.docx
ATIVIDADE 1 - SISTEMAS DISTRIBUÍDOS E REDES - 52_2024.docx2m Assessoria
 
Boas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsBoas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsDanilo Pinotti
 
Padrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploPadrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploDanilo Pinotti
 
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docxATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx2m Assessoria
 

Último (9)

ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docxATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
 
Luís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdfLuís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdf
 
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docxATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
 
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docxATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
 
Programação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdfProgramação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdf
 
ATIVIDADE 1 - SISTEMAS DISTRIBUÍDOS E REDES - 52_2024.docx
ATIVIDADE 1 - SISTEMAS DISTRIBUÍDOS E REDES - 52_2024.docxATIVIDADE 1 - SISTEMAS DISTRIBUÍDOS E REDES - 52_2024.docx
ATIVIDADE 1 - SISTEMAS DISTRIBUÍDOS E REDES - 52_2024.docx
 
Boas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsBoas práticas de programação com Object Calisthenics
Boas práticas de programação com Object Calisthenics
 
Padrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploPadrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemplo
 
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docxATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
 

Curso de Android Aula 4

  • 1. Google Android Jose Berardo Especializa Treinamentos 1
  • 2. Ementa 1. Introdução ao Android 2. Ambiente de desenvolvimento 3. Conceitos básicos 4. Application, Activities e Fragments 5. Intents e Broadcast Receivers 6. Views e Layout Managers 7. Persistência de dados e Content Providers 8. Shared Preferences 2
  • 3. Ementa Application, Activities e Fragments Android Application Mais sobre o Manifest.xml Activities Pilhas, estados e ciclo de vida Monitoramento de estados e LogCat Activity subclasses Fragments Estratégias de fragments em tablets x smartphones Ciclo de vida Fragment subclasses e suporte a APIs antigas 3
  • 4. O que faz uma aplicação? Tipos de objetos que fazem uma aplicação Android: Activity Objetos de classes que herdem de android.app.Activity Controladora da interface de cada tela Activities carregam Views e Fragments para exibir conteúdo ao cliente Service Objetos do tipo android.app.Service Trabalhadores invisíveis que executam tarefas em background Atualizam Activities, disparam Notifications e difundem Intents Suas tarefas em geral são longas ou constantes sem nenhuma interação direta com o usuário 4
  • 5. O que faz uma aplicação? Tipos de objetos que fazem uma aplicação Android: View Objetos de classes que herdem de android.view.View Representa cada componente na tela Gestores de layout herdam de sua subclasse abstrata android.view.ViewGroup Fragment Controladores de trechos de telas criados desde os primeiros tablets Android quando viram que uma Activity só para controlar essas telas maiores ficaria muito extensa São carregados por Activities, mas possuem seu próprio ciclo de vida 5
  • 6. O que faz uma aplicação? Tipos de objetos que fazem uma aplicação Android: Intent Objetos do tipo android.content.Intent Mecanismo de troca de mensagens interactivities e até mesmo interaplicações São extensamente usadas para abrir ou encerrar Activities ou Services, enviar mensagens em broadcast e muito mais Broadcast Receiver Intent listeners Fazem a aplicação reagir a determinadas Intents publicadas Constroem uma aplicação orientada a eventos 6
  • 7. O que faz uma aplicação? Tipos de objetos que fazem uma aplicação Android: Notification Possibilitam que sua aplicação alerte o usuário de determinada ação sem interromper o que ele estiver fazendo no momento Publicam na barra de notificações, em geral a partir de um Service ou Broadcast Receiver Content Provider Objetos do tipo android.content.ContentProvider Mecanismo compartilhável de armazenamento de dados que interage com bancos SQL Há diversos content providers nativos que nos dão acesso a bases como lista de contatos e mídias armazenadas 7
  • 8. O que faz uma aplicação? Tipos de objetos que fazem uma aplicação Android: Widget Componentes visuais que rodam direto na home screen São uma variação especial de Broadcast Receiver, permitindo interação com o usuário e execução direta Live Wallpaper Serviços com interatividade na home screen Widgets de fundos de tela responsivos 8
  • 9. Mais sobre o Manifest.xml Outros atributos da tag raiz <manifest> package - determina o nome único do projeto. É recomendado que você utilize o padrão do DNS invertido finalizando com o nome do projeto android:* - prefixo XML que carrega nós definidos no namespace http://schemas.android.com/apk/res/android installLocation - Local default de instalação da aplicação. Disponível desde a API 8 (Froyo - 2.2) internalOnly - Só admite que a aplicação seja instalada na memória interna do dispositivo preferExternal - Sugere que a aplicação seja instalada no SD card. Se esta estiver cheia ou indisponível no momento da instalação, o sistema vai instalar na memória interna auto - Utiliza as definições padrão do cliente 9
  • 10. Mais sobre o Manifest.xml Local de instalação da aplicação Instalar a app no SD card é bom por contar com mais espaço Mas quando o usuário utilizar o aparelho como USB mass storage, todas as apps instaladas no SD card serão encerradas Activities são fechadas Services são encerrados Alarmes são cancelados Widgets são removidos e Live Wallpapers são substituídos pelo default. Só voltam após o reinício da aplicação home. Em geral, quando ele reiniciar o aparelho A app não volta até a intervenção do usuário ou se estiver inscrita via BroadcastReceiver na Intent do sistema ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 10
  • 11. Mais sobre o Manifest.xml Apps que compartilham o mesmo usuário Cada app roda no Android em seu usuário único e seus recursos não são compartilhados para outros usuários O atributo sharedUserId pode ser usado para definir explicitamente uma string com o UID do usuário Duas apps podem definir o mesmo UID usando este atributo Têm acesso aos mesmos recursos como bases de dados Quando uma app chamar uma Activity de outra, esta segunda só rodará no mesmo processo (compartilhando até o que houver em memória) se tiver o mesmo sharedUserId As duas apps devem ter sido assinadas pelo mesmo certificado O atributo sharedUserString define um rótulo para o usuário 11
  • 12. Mais sobre o Manifest.xml Tag <uses-configuration> Filtram sua aplicação para só funcionar se tais configurações estiverem presentes Notadamente úteis para games com jogabilidade única ou avançada reqTouchScreen - Restringe a determinado tipo de touchscreen undefined, notouch, stylus (requer touchscreen com suporte a caneta) e finger reqKeyboardType - Restringe a deteminado tipo de teclado undefined, nokeys, qwerty (exige um teclado padrão qwerty - com as letras q, w, e, r, t e y na primeira linha) e twelvekey (exige um teclado padrão de simples celulares - números, * e #) 12
  • 13. Mais sobre o Manifest.xml Tag <uses-configuration> reqHardKeyboard - Booleano. Exige ou não presença de teclado físico. Caso preciso de um tipo específico, determine também reqKeyboardType reqNavigation - Restringe à presença de determinado mecanismo de navegação undefined, nonav, dpad (diretional pad), trackball, wheel reqFiveWayNav - Booleano. Exige ou não que o dispositivo tenha recursos de navegação direcional como trackball ou dpad 13
  • 14. Mais sobre o Manifest.xml Tags <uses-feature> Indica que sua aplicação só estará disponível se o hardware tiver determinada característica. Úteis para quando for imprescindível o uso de algum ou alguns recursos não disponíveis em todos os aparelhos O ideal é você nunca precisar citar nada aqui, mas caso necessite é bom restringir para evitar clientes frustrados O Google Play filtra a sua aplicação para só aparecer para quem estiver com hardware compatível com esta tag As características podem ser exigidas ou apenas recomendadas, mas todas as que precisarem de permissão do usuário são, por padrão, consideradas exigidas Para desligar esse filtro de exigência utilize o atributo required=“false” 14
  • 15. Mais sobre o Manifest.xml Tags <uses-feature> Atributos: name - especifica qual o recurso que você precisa. Ex.: android.hardware.bluetooth Podem ser de hardware: Audio, bluetooth, camera, location, microphone, nfc, sensor, screen, telephony, television, touchscreen, usb, wifi Ou sofware: live_wallpaper e sip (voip) Você pode conferir a lista completa aqui: developer.android.com/guide/topics/manifest/uses-feature- element.html#features-reference 15
  • 16. Mais sobre o Manifest.xml Tags <uses-feature> Atributos: required - determina se a característica é apenas uma boa indicação ou se chega a ser uma exigência glEsVersion - informa se há uma recomendação de versão do OpenGL ES (para gráficos). O valor é numérico de 32 bits expresso na base hexa, sendo os 16 primeiros reservados ao maior número da versão e os outros 16 ao menor número. glEsVersion=“0x00020001” - para a versão 2.1 (0002 -> 2 e 0001 ->1) Exemplos: <uses-feature android:name="android.hardware.camera" android:required="false"/> <uses-feature android:glEsVersion="0x00020001" android:required="true" /> 16
  • 17. Mais sobre o Manifest.xml Tags <uses-permission> Declara quais permissões a aplicação vai solicitar do usuário antes de ser instalada Basicamente, todas as operações que implicarem em custos ou questões de segurança precisam ser apresentadas ao cliente Traz apenas o atributo name e a lista possível nele é enorme 17
  • 18. Activity Principal classe para aplicativos que precisam da interação com o usuário Declaração mais básica de uma Activity no manifest Só é <activity android:label="@string/app_name" necessário .Classe por android:name=".MainActivity"> causa do package de </activity> <manifest> Construção fundamental da classe public class MainActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... } } 18
  • 19. Pilhas de Activities As activities são organizadas em pilhas (Last in first out) O estado delas é determinado pela sua posição na pilha Quando uma activity inicia, ela fica ativa no topo da pilha, quando o usuário aciona o botão back, a activity logo abaixo na pilha se torna ativa. 19
  • 20. package br.com.especializa.minhaprimeiraapp; import android.os.Bundle; Código gerado import android.app.Activity; pelo Hello World import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } A tarefa mais básica e comum do método onCreate é carregar alguma View através do método setContentView(). Ele vai instanciar os objetos Java referentes a cada tag desse layout e definir o que será exibido assim que Activity chegar no modo Running @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } 20
  • 21. Estados de uma Activity estados métodos callback 21
  • 22. Estados de uma Activity activity iniciada métodos estados chamados métodos callback 21
  • 23. Estados de uma Activity activity iniciada métodos estados chamados activity está ativa métodos callback 21
  • 24. Estados de uma Activity activity iniciada métodos estados chamados activity está ativa activity métodos está visível mas callback sem foco 21
  • 25. Estados de uma Activity activity iniciada métodos estados chamados activity está ativa activity está na memória mas não activity métodos está visível mas está visível callback sem foco 21
  • 26. Estados de uma Activity activity iniciada métodos estados chamados activity está ativa activity está na memória mas não activity métodos está visível mas está visível callback sem foco activity está encerrada 21
  • 27. Pilhas de Activities Para garantir que as activities vão reagir às mudanças de estado, o Android provê uma série de métodos de callback manipuladores de eventos Visão geral de todos os métodos do ciclo de vida activity activity onRestoreIntanceState onSaveIntanceState activity activity onResume onPause activity activity onStart onStop activity activity oncreate onDestroy activity onRestart Activity está ativa Activity está visível Tempo de vida completo da Activity 22
  • 28. Métodos de ciclo de vida onCreate(Bundle) Método principal onde normalmente as coisas são inicializadas Recebe um objeto bundle que empacota dados do estado anterior da Activity onStart() Método chamado imediatamente antes da Activity ficar visível Seguido de onResume() ou onStop() 23
  • 29. Métodos de ciclo de vida onResume() Chamado imediatamente antes da activity estar pronta para interagir com o usuário É sempre seguido de onPause() onPause() Método chamado no momento em que o sistema vai resumir outra Activity 24
  • 30. Métodos de ciclo de vida onStop() Chamado quando a activity não vai ficar mais visível Seguido de onRestart() se outra activity entrou na frente e saiu Seguido de onDestroy() se a activity for ser encerrada onRestart() Chamado quando a activity for voltar a ficar visível, antes do onStart() 25
  • 31. Métodos de ciclo de vida onDestroy() Chamado quando a activity for encerrar O método isFinishing() retorna true aqui se a activity vai encerrar por que o usuário fechou ou a aplicação chamou o método finish() Retorna false se o sistema resolveu encerrar a activity para liberar espaço em memória 26
  • 32. Logs do aplicativo A classe android.util.Log é útil para enviar informações no desenrolar do aplicativo Toda saída de sistema no Android (stdout e stderr) são direcionados para /dev/null, que significa que o bom e velho System.out.println() não vai funcionar O LogCat captura essas saídas de log e exibe as mensagens em cores diferentes: Código Nível Cor Log.v("categoria", "texto"); Verbose preto Log.d("categoria", "texto"); Debug azul Log.i("categoria", "texto"); Info verde Log.w("categoria", "texto"); Warning laranja Log.e("categoria", "texto"); Error vermelho 27
  • 33. package br.com.especializa.minhaprimeiraapp; import android.os.Bundle; import android.app.Activity; import android.util.Log; public class EstadosActivity extends Activity { ! @Override ! protected void onCreate(Bundle savedInstanceState) { ! ! super.onCreate(savedInstanceState); ! ! setContentView(R.layout.activity_estados); Exemplo de Logs para ! ! Log.i("LOG DO APLICATIVO", "Passou pelo onCreate"); monitoramento de ! } estados ! @Override ! protected void onStart() { ! ! super.onStart(); ! ! Log.i("LOG DO APLICATIVO", "Passou pelo onStart"); ! } ! @Override ! protected void onResume() { ! ! super.onResume(); ! ! Log.i("LOG DO APLICATIVO", "Passou pelo onResume"); ! } ! @Override ! protected void onRestart() { ! ! super.onRestart(); ! ! Log.i("LOG DO APLICATIVO", "Passou pelo onRestart"); ! } ! // já deu pra entender né? Crie logs em todos os métodos citados anteriormente } 28
  • 34. LogCat maximizado - DDMS Assim que iniciamos o aplicativo 29
  • 35. LogCat maximizado - DDMS Assim que iniciamos o Encerramos a aplicação aplicativo 29
  • 36. LogCat maximizado - DDMS Desligamos o visor Assim que iniciamos o (entrou a tela inicial), Encerramos a aplicação religamos e só então aplicativo encerramos a app 29
  • 37. Salvando estado da Activity Mesmo quando uma activity é pausada ou parada, seu estado é mantido em memória No entanto, o sistema pode destruir a activity para liberar memória, mesmo sem avisar ao usuário O sistema deverá ser capaz de recriar a activity de modo que retome seu estado original se o usuário quiser retornar a ela Existem métodos callback para lidar com as operação de registro de estado onSaveInstanceState - Chamado quando o sistema vai destruir a activity, mas sabe que precisa restaurar depois Quando o usuário clica em back, ele não é chamado onRestoreInstanceState - Logo antes do usuário solicitar novamente a activity destruída 30
  • 38. Salvando estado da activity 31
  • 39. Salvando estado da activity Objeto Bundle Objeto que empacota um java.util.Map Delega todos os seus métodos (putInt(), putString(), getInt(), getString() ...) Passado aos métodos onSaveInstanceState(), onRestoreInstanceState() e mesmo o onCreate() Através dele podemos salvar dados em onSaveInstanceState() e recuperar esses dados em onRestoreInstanceState() 32
  • 40. ! // Novos métodos em EstadosActivity /** ! * Método chamado quando o sistema resolver destruir ! * a activity atual em situações onde precisar recuperá-la de volta ! */ ! @Override ! protected void onSaveInstanceState(Bundle outState) { ! ! outState.putLong("momento", System.currentTimeMillis()); ! ! super.onSaveInstanceState(outState); ! ! Log.i("LOG DO APLICATIVO", "Passou pelo onSaveInstanceState"); ! } ! ! /** ! * Método chamado quando o sistema recuperar uma activity ! * destruída após chamada ao onSaveInstanceState ! */ ! @Override ! protected void onRestoreInstanceState(Bundle savedInstanceState) { ! ! // TODO Auto-generated method stub ! ! super.onRestoreInstanceState(savedInstanceState); ! ! Log.i("LOG DO APLICATIVO", "Passou pelo onRestoreInstanceState " + ! ! ! ! ! ! ! ! ! (System.currentTimeMillis() - ! ! ! ! ! ! ! ! ! savedInstanceState.getLong("momento")) + ! ! ! ! ! ! ! ! ! "ms depois do onSaveInstanceState"); ! } 33
  • 41. Salvando estado da activity Iniciamos a aplicação, o onRestoreInstanceState não foi chamado 34
  • 42. Salvando estado da activity O visor Iniciamos a esmaeceu após um aplicação, o tempo. onRestoreInstanceState onSaveInstanceState não foi chamado foi chamado 34
  • 43. Salvando estado da activity Desbloqueamos a tela O visor Iniciamos a reexibindo aapós um esmaeceu aplicação. aplicação, o onRestoreInstanceState ainda tempo. onRestoreInstanceState a não foi chamado porque onSaveInstanceState activityfoi chamado não não havia sido foi chamado destruída 34
  • 44. Salvando estado da activity Clicamos no back Desbloqueamos a tela O visor Iniciamosaaaplicacão. para encerra reexibindo aapós um esmaeceu aplicação. Como a activityo aplicação, não ainda onRestoreInstanceState é mais tempo. onRestoreInstanceState a necessária, não foi chamado porque onSaveInstanceState activityfoi chamado não não havia sido onSaveInstanceInstate foi chamado não foi chamado destruída 34
  • 45. Salvando estado da activity Iniciamos a aplicação e rotacionamos visor noa tela Desbloqueamos back Clicamos O Iniciamosaaaplicacão. para encerra o aparelho. Esse éreexibindo aapós um um caso aplicação. esmaeceu em que o sistema Como a activityo aplicação, não ainda onRestoreInstanceState é mais sempre tempo. onRestoreInstanceState a não foi necessária, destrói e reconstrói achamado porque onSaveInstanceState activity activityfoi chamado não não havia sido onSaveInstanceInstate foi chamado não foi chamado destruída 34
  • 46. Salvando estado da activity Curiosidade. Iniciamos a Quando a tela esmaece, e rotacionamos visor noa tela aplicação Desbloqueamos back Clicamos O Iniciamosaaaplicacão. para encerra a orientação da tela volta ao Esse éreexibindo aapós um o aparelho. um caso aplicação. esmaeceu estado inicial. Confiraque o sistema Como a activityo em os aplicação, não ainda onRestoreInstanceState é mais sempre tempo. onRestoreInstanceState a não foi necessária, métodos sendodestrói e reconstrói achamado porque onSaveInstanceState chamados activity activityfoi chamado não não havia sido onSaveInstanceInstate foi chamado não foi chamado destruída Voltaremos a este assunto na aula 6 ao falarmos mais sobre interfaces 34
  • 47. Activity subclasses Exemplos de subclasses: ListActivity - Activity que carrega ListViews para exibir coleções ExpandableListActivity - Activity que carrega ExpandableListViews TabActivity - Apresenta views em abas. Foi depreciada na API 13, em função dos fragments Aplicativos compilados com o extra Android Support Library poderão contar com FragmentActivity Trataremos deste assunto em Fragments Aplicativos compilados com a GoogleAPIs terão MapActivity Esse assunto será visto só em outro curso 35
  • 48. ListActivity Classe que empacota um ListView sem precisarmos escrever nenhum arquivo de layout Exibe uma lista vertical de itens, quando não couberem na tela, carrega uma barra de rolagem É uma Activity com alguns métodos para gerenciamento de listas Para preencher a lista, passamos um objeto de uma classe que herde de ListAdapter Vamos trabalhar agora com ArrayAdapter e em assuntos posteriores com SimpleCursorAdapter 36
  • 49. Activity subclasses Como não vamos criar uma view, vamos criar a Activity de outro jeito No Manifest, vá na aba Application e clique em add Mande criar uma Activity Em Attributes for Activity, clique em name para mandar gerar uma nova classe e preencha os demais atributos. É bem intuitivo. 37
  • 50. package br.com.especializa.minhaprimeiraapp; import android.app.ListActivity; import android.os.Bundle; import android.widget.ArrayAdapter; /** * Devemos herdar de ListActivity */ public class MinhaListaActivity extends ListActivity { ! @Override ! public void onCreate(Bundle savedInstanceState) { ! super.onCreate(savedInstanceState); ! // Valores que vão preencher a lista ! String[] instrumentos = {"violão", "guitarra", "bateria", "gaita", ! ! ! ! ! ! ! "microfone", "cajon", "bandolim", "congas", ! ! ! ! ! ! ! "violino", "piano", "contra-baixo", "panela"}; ! // ArrayAdapter que vai saber fornecer cada item ao ListView ! // context - this (toda Activity é um contexto) ! // android.R.layout.simple_item_1 - componente visual de cada linha ! // objetos - instrumentos - coleção de dados ! ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, ! ! ! ! ! ! ! ! android.R.layout.simple_list_item_1, ! ! ! ! ! ! ! ! instrumentos); ! // Método que define o adapter do ListView ! setListAdapter(adapter); ! } } 38
  • 51. package br.com.especializa.minhaprimeiraapp; import android.app.ListActivity; import android.os.Bundle; import android.widget.ArrayAdapter; /** * Devemos herdar de ListActivity */ public class MinhaListaActivity extends ListActivity { ! @Override ! public void onCreate(Bundle savedInstanceState) { ! super.onCreate(savedInstanceState); ! // Valores que vão preencher a lista ! String[] instrumentos = {"violão", "guitarra", "bateria", "gaita", ! ! ! ! Existe uma classe R padrão ! ! ! "microfone", "cajon", "bandolim", "congas", ! ! ! !do Android.! referencia todos ! ! Ela "violino", "piano", "contra-baixo", "panela"}; os componentes que podemos ! // ArrayAdapter que vai saber fornecer cada item ao ListView trabalhar ! // context - this (toda Activity é um contexto) ! // android.R.layout.simple_item_1 - componente visual de cada linha ! // objetos - instrumentos - coleção de dados ! ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, ! ! ! ! ! ! ! ! android.R.layout.simple_list_item_1, ! ! ! ! ! ! ! ! instrumentos); ! // Método que define o adapter do ListView ! setListAdapter(adapter); ! } } 38
  • 52. package br.com.especializa.minhaprimeiraapp; import android.app.ListActivity; import android.os.Bundle; import android.widget.ArrayAdapter; /** * Devemos herdar de ListActivity */ public class MinhaListaActivity extends ListActivity { ! @Override ! public void onCreate(Bundle savedInstanceState) { ! super.onCreate(savedInstanceState); ! // Valores que vão preencher a lista ! String[] instrumentos = {"violão", "guitarra", "bateria", "gaita", ! ! ! ! Existe uma classe R padrão ! ! ! "microfone", "cajon", "bandolim", "congas", ! ! ! !do Android.! referencia todos ! ! Ela "violino", "piano", "contra-baixo", "panela"}; os componentes que podemos ! // ArrayAdapter que vai saber fornecer cada item ao ListView trabalhar ! // context - this (toda Activity é um contexto) ! // android.R.layout.simple_item_1 - componente visual de cada linha ! // objetos - instrumentos - coleção de dados ! ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, ! ! ! ! ! ! ! ! android.R.layout.simple_list_item_1, ! ! ! ! ! ! ! ! instrumentos); ! // Método que define o adapter do ListView ! setListAdapter(adapter); ! } } 38
  • 53. ListAdapters Como vimos, servem para realizar o bind entre uma view e uma coleção de valores ArrayAdapter Carrega coleções arrays ou Lists em telas ListView CursorAdapter Listas maiores ou mais complexas precisam de um adapter mais inteligente do que o ArrayAdapter CursorAdapters unem cursores (objetos que gerenciam eficientemente coleções em buffers) e listviews Voltaremos a esse assunto quando fizermos consultas a bancos de dados 39
  • 54. Fragments São porções de tela por baixo de uma Activity É possível combinar mais de um Fragment numa tela Disponível desde a API 11 (Honeycomb) É possível decidir mostrar várias fragments em telas maiores (tablets) e continar usando navegação por activities (handsets) Disponível para APIs mais antigas (a partir da 4) através da Android Support Library No SDK Manager, vá aos extras e baixe esse pacote Seus próximos projetos já vão ser gerados com a inserção da dependência android-support-v4.jar 40
  • 57. ? Que tal começar por um exemplo do zero? 43
  • 58. Exemplo de Fragments 1.Crie uma nova Activity 1.1.Defina o nome FragmentsActivity.java. Por enquanto não vamos mudar o conteúdo padrão dela 1.2.Renomeie a view gerada para fragment_dois_lados.xml 2.Crie mais duas views 2.1.File > New > Other, depois Android > Android XML Layout File 2.2.Nomes: fragment_esquerda.xml e fragment_direita.xml 3.Crie duas classes Java no pacote src 3.1.FragmentEsquerda.java e FragmentDireita.java 3.2.Elas devem herdar de android.support.v4.app.Fragment 44
  • 59. View principal do fragment_dois_lados.xml exemplo. Carrega um layout em linha com dois elementos <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> ! <fragment ! ! android:name="br.com.especializa.minhaprimeiraapp.FragmentEsquerda" ! ! android:id="@+id/fragmentEsquerda" ! ! android:layout_weight="1" ! ! android:layout_width="0px" ! ! android:layout_height="match_parent" /> ! <fragment ! ! android:name="br.com.especializa.minhaprimeiraapp.FragmentDireita" ! ! android:id="@+id/fragmentDireita" ! ! android:layout_weight="1" ! ! android:layout_width="0px" Tags ! ! android:layout_height="match_parent" /> fragment indicam </LinearLayout> no atributo name o nome da classe controladora 45
  • 60. fragment_esquerda.xml Seu conteúdo é irrelevante no momento <?xml version="1.0" encoding="utf-8"?> <LinearLayout ! xmlns:android="http://schemas.android.com/apk/res/android" ! android:orientation="vertical" ! android:layout_width="fill_parent" ! android:layout_height="fill_parent" Mudamos a cor ! android:background="#00FF00"> do background só pra ! <TextView ficar destacar mais o ! ! android:layout_width="fill_parent" exemplo ! ! android:layout_height="wrap_content" ! ! android:text="Fragmento da esquerda" ! ! android:textColor="#000000" ! ! android:textSize="25sp" /> </LinearLayout> fragment_direita.xml Pode ter um conteúdo semelhante. Só altere a cor do fundo 46
  • 61. package br.com.especializa.minhaprimeiraapp; import android.os.Bundle; Vamos herdar de import android.support.v4.app.Fragment; Fragment da support import android.view.LayoutInflater; API import android.view.View; import android.view.ViewGroup; public class FragmentEsquerda extends Fragment { ! @Override ! public View onCreateView(LayoutInflater inflater, ViewGroup container, ! ! ! Bundle savedInstanceState) { ! ! // LayoutInflater é um objeto com a capacidade de ler um arquivo XML, ! ! // criar os objetos Java referentes a cada componente escrito lá ! ! // e exibi-lo em algum lugar. ! ! // Até então nós só havíamos conseguido isso com o setContentView() ! ! // do onCreate da Activity. ! ! // Que por sua vez carrega sempre na tela como um todo ! ! return inflater.inflate(R.layout.fragment_esquerda, container, false); ! } } No exemplo, Método callback do Chamada que FragmentDireita.java momento em que a view carrega a “sub” view deve ter a mesma principal for criada referenciada em R composição 47
  • 62. Como tudo aconteceu? FragmentsActivity.java setContentView(R.layout.fragment_dois_lados) Carregou a view principal fragment_dois_lados.xml Tags <fragment> Cada tag carregou uma classe Fragment FragmentEsquerda.java FragmentDireita.java inflater.inflate() inflater.inflate() Carregou fragment_esquerda.xml Carregou fragment_direita.xml fragment_esquerda.xml fragment_direita.xml Simples arquivo de layout Simples arquivo de layout 48
  • 63. O que ganhamos com isso? Telas maiores exibem mais informações Imagine A navegação não uma única Activity descarrega a tela para controlar todos os anterior seus eventos Cada Fragment controla a sua porção de tela 49
  • 64. No tablet, o resultado foi bom 50
  • 66. Fragments Podemos detectar de alguma forma que a tela é grande e só então exibir dois fragments Se a tela for menor, exibiremos apenas um fragment Este fragment irá abrir outra Activity com o segundo fragment dentro 1. Crie um novo arquivo XML de layout 1.1.Chame-o de fragment_um_lado.xml 2. Altere a Activity principal para escolher entre ele ou o de dois lados 52
  • 67. Um ou dois fragments FragmentsActivity.java OU setContentView fragment_um_lado.xml fragment_dois_lados.xml FragmentEsquerda.java FragmentDireita.java fragment_esquerda.xml fragment_direita.xml 53
  • 68. fragment_um_lado.xml Apenas um fragment <?xml version="1.0" encoding="utf-8"?> <fragment xmlns:android="http://schemas.android.com/apk/res/android" ! android:name="br.com.especializa.minhaprimeiraapp.FragmentEsquerda" ! android:id="@+id/fragmentEsquerda" ! android:layout_width="match_parent" ! android:layout_height="match_parent" /> 54
  • 69. 1. @Override 2. protected void onCreate(Bundle savedInstanceState) { 3. super.onCreate(savedInstanceState); 4. boolean doisPaineis = false; 5. 6. // Verificamos se a tela é padrão XLARGE 7. if ((getResources().getConfiguration().screenLayout 8. & Configuration.SCREENLAYOUT_SIZE_XLARGE) 9. ! == Configuration.SCREENLAYOUT_SIZE_XLARGE) { 10. 11. ! Toast.makeText(this, "XLARGE", Toast.LENGTH_LONG).show(); 12. ! doisPaineis = true; 13. 14. // Verificamos se a tela é padrão LARGE 15. } else if ((getResources().getConfiguration().screenLayout & 16. Configuration.SCREENLAYOUT_SIZE_LARGE) 17. ! == Configuration.SCREENLAYOUT_SIZE_LARGE) { 18. 19. ! Toast.makeText(this, "LARGE", Toast.LENGTH_LONG).show(); 20. ! doisPaineis = true; 21. 22. } 23. 24. if (doisPaineis) { 25. setContentView(R.layout.fragment_dois_lados); 26. } else { 27. setContentView(R.layout.fragment_um_lado); 28. } 29. } 55
  • 70. Fragments Nas linhas 7 e 15 getResources() retornou o objeto Resources a partir do qual se obtém dados dos recursos do dispositivo getConfiguration() retornou dados da configuração corrente screenLayout trouxe uma máscara de bits sobre o tamanho da tela Perguntamos se a máscara de bits casa com o padrão XLARGE ou LARGE Nesses casos, e só nesses casos, doisPaineis virou true E chamamos fragments_dois_lados 56
  • 71. Fragments Como vamos exibir o layout fragment_direita.xml? Ele deverá vir a partir de uma nova Activity Esta nova Activity não vai controlar a view do fragment Essa tarefa já ficou a cargo da classe DireitaFragment.java 1. Vamos criar um botão em fragment_esquerda.xml 2. Implementar o evento de clique no EsquerdaFragment.java 2.1. Será feito no novo método callback onActivityCreate() 3. Criar a nova Activity chamada DireitaFragmentActivity.java 57
  • 72. Exemplo completo Activity1 Activity2 FragmentsActivity.java FragmentDireitaActivity.java OU setContentView fragment_um_lado.xml fragment_dois_lados.xml FragmentManager FragmentTransaction FragmentEsquerda.java FragmentDireita.java fragment_esquerda.xml fragment_direita.xml click no botão 58
  • 73. <?xml version="1.0" encoding="utf-8"?> <LinearLayout ! xmlns:android="http://schemas.android.com/apk/res/android" ! android:orientation="vertical" ! android:layout_width="fill_parent" ! android:layout_height="fill_parent" ! android:background="#00FF00"> ! <TextView ! ! android:layout_width="fill_parent" ! ! android:layout_height="wrap_content" ! ! android:text="Fragmento da esquerda" ! ! android:textColor="#000000" Novo botão em ! ! android:textSize="25sp" /> fragment_esquerda.xml ! <Button ! android:id="@+id/btnChamarDireita" ! android:layout_width="wrap_content" ! android:layout_height="wrap_content" ! android:text="Chamar direita" /> </LinearLayout> 59
  • 74. Novo método em getActivity() recupera a FragmentEsquerda.java Activity associada ao Fragment @Override public void onActivityCreated(Bundle savedInstanceState) { ! super.onActivityCreated(savedInstanceState); ! ! Button b = (Button) getActivity().findViewById(R.id.btnChamarDireita); ! b.setOnClickListener(new View.OnClickListener() { ! ! ! ! @Override ! ! public void onClick(View v) { ! ! ! if (getActivity().findViewById(R.id.fragmentDireita) == null) { ! ! ! ! Intent i = new Intent(getActivity(), FragmentDireitaActivity.class); ! ! ! ! getActivity().startActivity(i); ! ! ! } ! ! } ! }); ! } A chamada à próxima Activity precisa da criação de Intents. Assunto da próxima aula 60
  • 75. package br.com.especializa.minhaprimeiraapp; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; public class FragmentDireitaActivity extends FragmentActivity { ! @Override ! protected void onCreate(Bundle savedInstanceState) { ! ! super.onCreate(savedInstanceState); Novo objeto em ! ! Fragment fragment = new FragmentDireita(); FragmentDireita que vai controlar a view. O papel desta ! ! getSupportFragmentManager().beginTransaction() Activity é apenas criá-lo ! ! .add(android.R.id.content, fragment).commit(); ! ! ! } } - getSupportFragmentManager() retorna o objeto FragmentManager. - Seu método beginTransation() é quem adiciona, remove ou substitui fragments ao layout da Activity atual - android.R.id.content referencia a raiz de elementos da View - commit() realiza a operação 61
  • 76. O ciclo de vida do Fragment é parecido e vinculado ao de uma Activity Se a Activity parar, seus fragments também param. Se for destruída, eles também serão onAttach(Activity) Chamado assim que o fragment for anexado a uma Activity. Ela é passada como parâmetro onCreate(Bundle) Semelhante ao da Activity. É chamado para fazer suas inicializações 62
  • 77. onCreateView(LayoutInflater, ViewGroup, Bundle) O método mais usado em um Fragment representa o momento exato em que ele cria sua interface com o usuário Recebe o inflater que vai carregar a view, o ViewGroup que servirá de container e o mesmo bundle do onCreate onActivityCreated(Bundle) Chamado logo depois da Activity ser criada Como Fragments não herdam de Context, precisam sempre chamar a Activity para conseguir realizar algumas operações de conteúdo Lembra do Toast, por exemplo? A partir daqui getActivity() não retorna nulo 63
  • 78. onStart() Chamado logo quando o Fragment estiver visível onResume() Chamado logo quando ele assumir interatividade com o usuário onPause() Chamado assim que ele perder a interatividade onStop() Chamado assim que a Activity não estiver mais visível 64
  • 79. onDestroyView(LayoutInflater, ViewGroup, Bundle) Método parecido com o onCreateView() Roda no momento em que a view carregada nele for destruída onDestroy() Roda assim que o fragment não tiver mais serventia onDetach() Roda quando não estiver mais anexado a uma Activity 65
  • 80. Fragment subclasses Há duas versões de Fragments Elas possuem estruturas hierárquicas diferentes android.app.Fragment Classe adicionada na API 11 (honeycomb) justamente no momento da ascensão dos tablets Herdada por DialogFragment, ListFragment, PreferenceFragment e WebViewFragment android.support.v4.app.Fragment Classe da API Android Suppor V4, que é o extra que porta os fragments lá pra trás na API 4 (Donut - 1.6) Herdada apenas por DialogFragment e ListFragment sendo as respectivas classes criadas neste mesmo pacote Não são as mesmas do pacote principal 66
  • 81. Suporte a APIs antigas Apps com Fragments compatíveis com APIs antigas: Os fragments devem ser android.support.v4.app.Fragment As activities que anexam fragments devem herdar de android.support.v4.app.FragmentActivity Nelas, o objeto FragmentManager deve ser o do pacote android.support.v4.app, chamado exclusivamente por getSupportFragmentManager(), um método com função semelhante ao getFragmentManager() ListFragments e DialogFragments só podem ser do mesmo pacote da API de suporte APIs v7 e v13 São supersets da v4 e trazem mais coisas, mas requerem minSdkVersion 7 e 13 respectivamente 67
  • 82. ? Vamos analisar o código gerado pelo MasterDetailFlow 68
  • 83. Esta foi a Activity principal <!-- Trecho no AndroidManifest.xml referente ao MasterDetailFlow que criamos --> <activity android:name="br.com.especializa.minhaprimeiraapp.ProdutoListActivity" android:label="@string/title_produto_list" > <intent-filter> <action android:name="android.intent.action.MAIN" /> A segunda Activity <category android:name="android.intent.category.LAUNCHER" /> para quando a tela for </intent-filter> menor </activity> <activity android:name="br.com.especializa.minhaprimeiraapp.ProdutoDetailActivity" android:label="@string/title_produto_detail" android:parentActivityName=".ProdutoListActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".ProdutoListActivity" /> Atributo criado no Jelly </activity> Bean 4.1 (API 16) Versão anterior à da API 16 para a mesma idéia 69
  • 84. Navegação Up A API 11 trouxe também as ActionBars e com elas, o chamado Up button As declarações do AndroidManifest definiram a Activity a ser chamada quando este botão for acionado <meta name="android.support.PARENT_ACTIVITY"> Para APIs anteriores à 16 android:parentActivityName="" Para versões posteriores 70
  • 85. Navegação Up e Back Up button disponível em telas internas Back button de sempre 71
  • 86. package br.com.especializa.minhaprimeiraapp; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class ProdutoListActivity extends FragmentActivity implements Interface ! ! ProdutoListFragment.Callbacks { criada pelo próprio exemplo ! private boolean mTwoPane; ! @Override ! protected void onCreate(Bundle savedInstanceState) { ! ! super.onCreate(savedInstanceState); ! ! // Layout que só carrega um único Fragment ! ! // Vai ser trocado por outro usando um técnica bem legal ! ! setContentView(R.layout.activity_produto_list); ! ! // De cara, parace que nunca vai entrar nesse if ! ! if (findViewById(R.id.produto_detail_container) != null) { ! ! ! // Se entrar, essa variável vira true ! ! ! mTwoPane = true; O estilo do ícone vai ! ! ! ((ProdutoListFragment) getSupportFragmentManager() permanecer ! ! ! ! ! .findFragmentById(R.id.produto_list)) clicado ! ! ! ! ! .setActivateOnItemClick(true); ! ! } ! } ! // continua ... 72
  • 87. ! // Método que a interface criada exigiu que fosse implementado // O fragment controlador da lista vai invocá-lo de volta (Callback) ! @Override ! public void onItemSelected(String id) { ! ! if (mTwoPane) { ! ! ! // Em tela dupla (tablets), vamos criar um Bundle // para armazenar o id do produto clicado ! ! ! Bundle arguments = new Bundle(); ! ! ! arguments.putString(ProdutoDetailFragment.ARG_ITEM_ID, id); ! ! ! ProdutoDetailFragment fragment = new ProdutoDetailFragment(); ! ! ! fragment.setArguments(arguments); // Método que registra o bundle no Fragment // Substituindo o fragment de detalhes que estiver carregado por outro atualizado ! ! ! getSupportFragmentManager().beginTransaction() ! ! ! ! ! .replace(R.id.produto_detail_container, fragment).commit(); ! ! } else { ! ! ! // Em telas simples, haverá uma chamada à nova Activity que vai ! ! ! // receber no pacote o id do produto clicado // ... calma que ainda veremos Intents ! ! ! Intent detailIntent = new Intent(this, ProdutoDetailActivity.class); ! ! ! detailIntent.putExtra(ProdutoDetailFragment.ARG_ITEM_ID, id); ! ! ! startActivity(detailIntent); ! ! } ! } } 73
  • 88. activity_produto_list.xml Apenas um fragment gerado <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/produto_list" android:name="br.com.especializa.minhaprimeiraapp.ProdutoListFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" tools:context=".ProdutoListActivity" tools:layout="@android:layout/list_content" /> Tablets, que possuem telas grandes e APIs >= 11, vão sobrescrever a referência de <resources> R ao layout de um fragment <item name="activity_produto_list" type="layout"> pelo de dois @layout/activity_produto_twopane </item> </resources> refs.xml em values-large Fez sentido o if (nomenclatura antiga) e (mTwoPane) da values-sw600dp (nova) Activity? 74
  • 89. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:divider="?android:attr/dividerHorizontal" android:orientation="horizontal" android:showDividers="middle" tools:context=".ProdutoListActivity" > <fragment android:id="@+id/produto_list" android:name="br.com.especializa.minhaprimeiraapp.ProdutoListFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" tools:layout="@android:layout/list_content" /> activity_produto_twopane.xml <FrameLayout android:id="@+id/produto_detail_container" carregando um fragment android:layout_width="0dp" produto_list e um outro componente android:layout_height="match_parent" produto_detail_container android:layout_weight="3" /> </LinearLayout> 75
  • 90. ListFragment da API de suporte public class ProdutoListFragment extends ListFragment { ! private static final String STATE_ACTIVATED_POSITION = "activated_position"; ! private Callbacks mCallbacks = sDummyCallbacks; ! private int mActivatedPosition = ListView.INVALID_POSITION; Representa ! /** posição inválida do ! * Interface interna que a Activity principal implementou toque no item ! */ ! public interface Callbacks { ! ! /** ! ! * Método implementado pela Activity principal ! ! */ ! ! public void onItemSelected(String id); ! } ! @Override Lembra do ! public void onCreate(Bundle savedInstanceState) { ! ! super.onCreate(savedInstanceState); ArrayAdapter? ! ! // TODO: replace with a real list adapter. ! ! setListAdapter(new ArrayAdapter<DummyContent.DummyItem>(getActivity(), ! ! ! ! android.R.layout.simple_list_item_activated_1, ! ! ! ! android.R.id.text1, DummyContent.ITEMS)); ! } // continua ... 76
  • 91. Assim que a view for criada. Ela é recriada em rotações ! @Override ! public void onViewCreated(View view, Bundle savedInstanceState) { ! ! super.onViewCreated(view, savedInstanceState); ! ! // Recuperando um possível valor de item selecionado ! ! if (savedInstanceState != null ! ! ! ! && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) { ! ! ! setActivatedPosition(savedInstanceState ! ! ! ! ! .getInt(STATE_ACTIVATED_POSITION)); ! ! } ! } Frescurinha ! @Override particular do código ! public void onAttach(Activity activity) { gerado ! ! super.onAttach(activity); ! ! // Activities containing this fragment must implement its callbacks. ! ! if (!(activity instanceof Callbacks)) { ! ! ! throw new IllegalStateException( ! ! ! ! ! "Activity must implement fragment's callbacks."); ! ! } ! ! mCallbacks = (Callbacks) activity; ! } // Continua ... 77
  • 92. ! @Override Quando o item for ! public void onDetach() { ! ! super.onDetach(); selecionado, chama o ! ! mCallbacks = sDummyCallbacks; callback da activity ! } ! @Override ! public void onListItemClick(ListView listView, View view, int position, ! ! ! long id) { ! ! super.onListItemClick(listView, view, position, id); ! ! mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id); ! } ! @Override ! public void onSaveInstanceState(Bundle outState) { ! ! super.onSaveInstanceState(outState); ! ! if (mActivatedPosition != ListView.INVALID_POSITION) { ! ! ! // Serialize and persist the activated item position. ! ! ! outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition); ! ! } ! } // Continua ... Salvando o item selecionado 78
  • 93. ! public void setActivateOnItemClick(boolean activateOnItemClick) { ! ! // When setting CHOICE_MODE_SINGLE, ListView will automatically ! ! // give items the 'activated' state when touched. ! ! getListView().setChoiceMode( Redefinição ! ! ! ! activateOnItemClick ? ListView.CHOICE_MODE_SINGLE ! ! ! ! ! ! : ListView.CHOICE_MODE_NONE); inusitada de métodos ! } sobre a marcação de itens selecionados ! private void setActivatedPosition(int position) { ! ! if (position == ListView.INVALID_POSITION) { ! ! ! getListView().setItemChecked(mActivatedPosition, false); ! ! } else { ! ! ! getListView().setItemChecked(position, true); ! ! } ! ! mActivatedPosition = position; ! } } 79
  • 94. /** * Activity de detalhes para hansets */ public class ProdutoDetailActivity extends FragmentActivity { ! @Override Carregou a view ! protected void onCreate(Bundle savedInstanceState) { ! ! super.onCreate(savedInstanceState); porque não houve um ! ! setContentView(R.layout.activity_produto_detail); fragment da direita no exemplo ! ! // Exibindo o Up button ! ! getActionBar().setDisplayHomeAsUpEnabled(true); ! ! if (savedInstanceState == null) { ! ! ! // Criando o fragment da direita ! ! ! Bundle arguments = new Bundle(); ! ! ! arguments.putString(ProdutoDetailFragment.ARG_ITEM_ID, getIntent() ! ! ! ! ! .getStringExtra(ProdutoDetailFragment.ARG_ITEM_ID)); ! ! ! ProdutoDetailFragment fragment = new ProdutoDetailFragment(); ! ! ! fragment.setArguments(arguments); ! ! ! getSupportFragmentManager().beginTransaction() ! ! ! ! ! .add(R.id.produto_detail_container, fragment).commit(); ! ! } ! } ! @Override ! public boolean onOptionsItemSelected(MenuItem item) { Callback do evento ! ! switch (item.getItemId()) { de clique no botão ! ! case android.R.id.home: options do Android ! ! ! NavUtils.navigateUpTo(this, new Intent(this, ! ! ! ! ! ProdutoListActivity.class)); ! ! ! return true; ! ! } ! ! return super.onOptionsItemSelected(item); ! } } 80
  • 95. ? Que tal fazer um ListFragment do zero? 81