Por que fragmentos e quando usar fragmentos em vez de atividades?

485

Na API Android 11+, o Google lançou uma nova classe chamada Fragment.

Nos vídeos, o Google sugere que, sempre que possível ( link1 , link2 ), devemos usar fragmentos em vez de atividades, mas eles não explicaram exatamente o porquê.

Qual é o objetivo dos fragmentos e alguns usos possíveis deles (além de alguns exemplos de interface do usuário que podem ser facilmente alcançados por visualizações / layouts simples)?

Minha pergunta é sobre fragmentos:

  1. Quais são os propósitos de usar um fragmento?
  2. Quais são as vantagens e desvantagens do uso de fragmentos em comparação ao uso de atividades / visualizações / layouts?

Perguntas sobre bônus:

  1. Você pode dar alguns usos realmente interessantes para fragmentos? O que o Google não mencionou em seus vídeos?
  2. Qual é a melhor maneira de se comunicar entre os fragmentos e as atividades que os contêm?
  3. Quais são as coisas mais importantes a serem lembradas quando você usa fragmentos? Alguma dica e aviso de sua experiência?
desenvolvedor android
fonte

Respostas:

282

# 1 e # 2 quais são os objetivos do uso de um fragmento e quais são as vantagens e desvantagens do uso de fragmentos em comparação com o uso de atividades / visualizações / layouts?

Fragmentos são a solução do Android para criar interfaces de usuário reutilizáveis. Você pode obter as mesmas coisas usando atividades e layouts (por exemplo, usando inclusões). Contudo; fragmentos são conectados à API do Android, do HoneyComb e superiores. Deixe-me elaborar;

  • A ActionBar. Se você quiser que as guias lá em cima naveguem no seu aplicativo, você verá rapidamente que a ActionBar.TabListenerinterface fornece um FragmentTransactionargumento de entrada para o onTabSelectedmétodo. Você provavelmente poderia ignorar isso e fazer algo mais inteligente, mas estaria trabalhando contra a API, não com ela.

  • As FragmentManageralças «de volta» para você de uma maneira muito inteligente. Voltar não significa voltar para a última atividade, como para atividades regulares. Isso significa voltar ao estado anterior do fragmento.

  • Você pode usar o cool ViewPagercom um FragmentPagerAdapterpara criar interfaces de furto. O FragmentPagerAdaptercódigo é muito mais limpo do que um adaptador comum e controla instanciações dos fragmentos individuais.

  • Sua vida será muito mais fácil se você usar fragmentos ao tentar criar aplicativos para telefones e tablets. Como os fragmentos estão tão ligados às APIs do Honeycomb +, convém usá-los nos telefones também para reutilizar o código. É aí que a biblioteca de compatibilidade é útil.

  • Você ainda pode e deve usar fragmentos para aplicativos destinados apenas a telefones. Se você tem portabilidade em mente. Eu uso ActionBarSherlocke as bibliotecas de compatibilidade para criar aplicativos "com aparência de ICS", que têm a mesma aparência desde a versão 1.6. Você obtém os recursos mais recentes, como ActionBar, com guias, estouro, barra de ação dividida, visor, etc.

Bônus 2

A melhor maneira de se comunicar entre fragmentos é a intenção. Quando você pressiona algo em um fragmento, você normalmente chama StartActivity()com dados. A intenção é passada a todos os fragmentos da atividade que você inicia.

Glenn Bech
fonte
5
Antes de tudo, obrigado.Eu aprecio as pessoas que dão respostas informativas (mas curtas) e não apenas me fornecem um link para um manual. ?
desenvolvedor android
4
Eu acho que você tem que ser mais direto no seu questionamento. Eu acabei de dar quatro grandes vantagens acima.
Glenn Bech
2
ok, e quanto às desvantagens em comparação com visualizações e atividades personalizadas?
desenvolvedor android
2
como você se comunica entre fragmentos usando intenções? todos os fragmentos precisam estar "vivos" (adicionados à atividade) para que eles possam se comunicar?
android developer
55
Um fragmento nunca deve falar diretamente com outro fragmento - em vez disso, passe pela atividade pai. Dessa forma, você não acaba com o código espaguete, mas é fácil de gerenciar.
Slott
70

Não tenho certeza de quais vídeos você está se referindo, mas duvido que estejam dizendo que você deve usar fragmentos em vez de atividades, porque eles não são diretamente intercambiáveis. Na verdade, há uma entrada bastante detalhada no Guia do desenvolvedor, considere a leitura para obter detalhes.

Em resumo, os fragmentos vivem dentro de atividades e cada atividade pode hospedar muitos fragmentos. Como as atividades, eles têm um ciclo de vida específico, ao contrário das atividades, eles não são componentes de aplicativos de nível superior. As vantagens dos fragmentos incluem a reutilização de código e a modularidade (por exemplo, usando a mesma exibição de lista em muitas atividades), incluindo a capacidade de criar interfaces de vários painéis (principalmente úteis em tablets). A principal desvantagem é (algumas) maior complexidade. Geralmente, você pode obter o mesmo com visualizações (personalizadas) de uma maneira não padrão e menos robusta.

Nikolay Elenkov
fonte
1
pergunta atualizada. agora tem links para os vídeos do google. Além disso, obrigado pela explicação, mas ainda preciso de esclarecimentos sobre minha pergunta.
desenvolvedor android
5
Leia a entrada do guia do desenvolvedor, que possui detalhes mais que suficientes. É improvável que você obtenha uma resposta para 'usos legais de fragmentos' no SO - muito vagamente e não há uma resposta única. Número 4 é specificlly respondeu no dev guide-- developer.android.com/guide/topics/fundamentals/...
Nikolay Elenkov
1
Até onde eu sei, esse método cria uma dependência de qual atividade pode conter qual fragmento. Além disso, responda às principais perguntas (as duas primeiras).
desenvolvedor android
3
Agradecemos ao desenvolvedor do Android por insistir nas respostas à pergunta básica. ATM: Eu não vi nada útil para mim na classe Fragment sobre o uso da tag XML "include". O tipo de coisa que eu consideraria valiosa seria a capacidade de especificar um layout que se transformaria magicamente na melhor experiência do usuário em todas as resoluções. Pelo que posso dizer, você ainda precisa fazer isso no código sozinho. Outro valor potencial seria uma maneira de agrupar código + recursos em componentes reutilizáveis ​​não encontrados nos aplicativos reutilizados, mas novamente não parece estar lá. Eu quero uma realmente boa razão.
Melinda Green
2
Estou começando a compreender a forma como o Google sugerir o uso de fragmentos, mas bastante concordar com @NikolayElenkov .. Para mim, usando atividades ainda parece ser o mais robusto e da maneira menos complexa ..
andrea.rinaldi
49

Um fragmento é uma parte da interface do usuário ou comportamento de um aplicativo que pode ser colocada em uma atividade que permite um design de atividade mais modular. Não estará errado se dissermos que um fragmento é um tipo de subatividade.

A seguir, são apresentados pontos importantes sobre um fragmento:

  1. Um fragmento tem seu próprio layout e seu próprio comportamento com seus próprios retornos de chamada do ciclo de vida.

  2. Você pode adicionar ou remover fragmentos em uma atividade enquanto ela estiver em execução.

  3. Você pode combinar vários fragmentos em uma única atividade para criar uma interface do usuário com vários painéis.

  4. Um fragmento pode ser usado em várias atividades.

  5. O ciclo de vida do fragmento está intimamente relacionado ao ciclo de vida da atividade do host.

  6. Quando a atividade é pausada, todos os fragmentos disponíveis na atividade também serão parados.

  7. Um fragmento pode implementar um comportamento que não possui componente de interface do usuário.

  8. Fragmentos foram adicionados à API do Android no Android 3 (Honeycomb) com a API versão 11.

Para mais detalhes, visite o site oficial, Fragments .

mani
fonte
1. Como você mencionou no item 8, ele não precisa ter um layout. 6. você perdeu a parte depois de "significa". De qualquer forma, obrigado por ajudar os outros a deixar isso mais claro. Eu te darei +1.
desenvolvedor android
1
Em relação ao item 8, um possível exemplo de fragmento sem layout (ou seja, fragmento 'sem cabeça') seria aquele que executa uma tarefa que, apesar de ser um pouco curta (como uma solicitação HTTP curta), ainda é necessária para sobreviver às alterações de configuração e, portanto, depende na instância exata do fragmento sendo preservada entre eles (usando setRetainInstance (true) no fragmento). Quanto aos fragmentos de layout, setRetainInstance (true) não faz muito sentido, pois impede que os recursos associados às suas visualizações sejam liberados quando necessário (por exemplo, um vazamento de memória).
Piovezan
NOTA: "# 8" agora é "# 7".
Página
21

Esta é uma informação importante que encontrei nos fragmentos:

Historicamente, cada tela em um aplicativo Android era implementada como uma Atividade separada. Isso cria um desafio ao passar informações entre telas porque o mecanismo Android Intent não permite a passagem de um tipo de referência (ou seja, objeto) diretamente entre as Atividades. Em vez disso, o objeto deve ser serializado ou disponibilizada uma referência globalmente acessível.

Ao tornar cada tela um fragmento separado, essa dor de cabeça que passa pelos dados é completamente evitada. Os fragmentos sempre existem no contexto de uma determinada atividade e sempre podem acessar essa atividade. Armazenando as informações de interesse na Atividade, o Fragmento para cada tela pode simplesmente acessar a referência do objeto através da Atividade.

Fonte: https://www.pluralsight.com/blog/software-development/android-fragments

Kaveesh Kanwal
fonte
3
Isso é verdade, mas existem soluções para isso: use Parcelable quando não for um objeto enorme (e existe um plug-in para facilitar) e, se for um objeto enorme, você sempre poderá usar uma referência estática que será definida como nula quando você chega à nova atividade (ou quando a destrói, dependendo da sua exigência).
desenvolvedor android
@androiddeveloper: "use Parcelable" se encaixa na minha definição de "dor de cabeça que passa de dados que é evitada pelo uso de fragmentos". Se houver um estado compartilhado complexo que precisa persistir enquanto uma série de telas passa, um Activity + Fragments é uma boa solução, IMHO. (Embora eu abandonei a pilha de volta Fragmento, e fiz a minha própria gestão do que significa "volta".)
ToolmakerSteve
Usar o padrão de design de interface entre fragmentos por meio de uma atividade de contêiner é uma abordagem muito modular para passar não apenas objetos, mas também clicar em listeners de eventos e argumentos de método de volta para outros fragmentos ou para a atividade principal de contêiner.
Kaveesh Kanwal #
10

As atividades são os componentes de tela cheia no aplicativo com a barra de ferramentas; todo o resto são de preferência fragmentos. Uma atividade pai em tela cheia com uma barra de ferramentas pode ter vários painéis, páginas roláveis, caixas de diálogo etc. (todos os fragmentos), os quais podem ser acessados ​​pelo pai e comunicados por ele.

Exemplo:

Atividade A, Atividade B, Atividade C:

  • Todas as atividades precisam ter o mesmo código repetido, para mostrar uma barra de ferramentas básica, por exemplo, ou herdar de uma atividade pai (torna-se complicado de gerenciar).
  • Para passar de uma atividade para outra, todas elas precisam estar na memória (sobrecarga) ou uma precisa ser destruída para a outra abrir.
  • A comunicação entre as atividades pode ser feita via Intenções.

vs

Atividade A, Fragmento 1, Fragmento 2, Fragmento 3:

  • Sem repetição de código, todas as telas possuem barras de ferramentas etc. dessa atividade.
  • Várias maneiras de passar de um fragmento para o próximo - visualizar pager, vários painéis etc.
  • A atividade tem mais dados, portanto, é necessária uma comunicação mínima entre fragmentos. Se ainda necessário, pode ser feito via interfaces facilmente.
  • Os fragmentos não precisam ter tela cheia, muita flexibilidade para projetá-los.
  • Fragmentos não precisam aumentar o layout se as visualizações não forem necessárias.
  • Várias atividades podem usar o mesmo fragmento.
Chandrima Bhattacharjee
fonte
resposta perfeita!
Sathesh
8

Fragmentos são de uso particular em alguns casos, como onde queremos manter uma gaveta de navegação em todas as nossas páginas. Você pode inflar um layout de quadro com qualquer fragmento que desejar e ainda ter acesso à gaveta de navegação.

Se você tivesse usado uma atividade, teria que manter a gaveta em todas as atividades, o que resulta em código redundante. Este é um uso interessante de um fragmento.

Eu sou novo no Android e ainda acho que um fragmento é útil dessa maneira.

Nithin Baby
fonte
Sim. No entanto, às vezes ainda estou confuso sobre a maneira correta de usar fragmentos, e isso é devido ao ciclo de vida complexo de fragmentos e atividades.
developer android
@androiddeveloper você apenas usa atividades principalmente?
Michael Alan Huff
@MichaelAlanHuff Ao oferecer suporte a tablets, acho melhor usar Fragments. Além disso, ao oferecer suporte a alterações de orientação e outros eventos semelhantes, convém usar o DialogFragment, pois permite restaurá-los
desenvolvedor Android
@androiddeveloper, é o que eu acho também. Eu não usei DialogFragments com tanta frequência. Por ajudar a modularidade da lógica, muitos desenvolvedores de Android estão começando a usar visualizações personalizadas para manter a lógica à mão. Aqui está uma conversa recente sobre exibições personalizadas dado por um engenheiro da Airbnb vimeo.com/127799187
Michael Alan Huff
@MichaelAlanHuff usando fragmentos também pode ser útil se você acha que a tela atual pode fazer parte de outra tela.
desenvolvedor android
5

Eu sei que isso já foi discutido até a morte, mas eu gostaria de acrescentar mais alguns pontos:

  • Frags podem ser usados ​​para preencher Menus e podem lidar com MenuItemcliques por conta própria. Dando assim mais opções de modulação para suas atividades. Você pode fazer coisas de ContextualActionBar e assim por diante sem que sua Atividade saiba sobre isso e basicamente pode separá-las das coisas básicas que sua Atividade lida (Navegação / Configurações / Sobre).

  • Um Frag pai com Frags filho pode oferecer outras opções para modular seus componentes. Por exemplo, você pode facilmente trocar Frags, colocar novas Frags dentro de um Pager ou removê-las, reorganizá-las. Tudo sem a sua atividade saber nada sobre ela, apenas focando nas coisas de nível superior.

einschnaehkeee
fonte
0

Fragments vive dentro da Atividade e possui:

  • seu próprio ciclo de vida
  • seu próprio layout
  • seus próprios fragmentos filhos e etc.

Pense em Fragmentos como uma sub atividade da atividade principal a que pertence, não pode existir por si só e pode ser chamado / reutilizado repetidamente. Espero que isto ajude :)

maniix
fonte
Na verdade, sobre o segundo ponto ("seu próprio layout"), isso é opcional. Um fragmento não precisa ter uma visualização.
desenvolvedor android
0

1. Objetivos do uso de um fragmento?

  • Resp:
    1. Lidar com diferenças de fator de forma do dispositivo.
    2. Passando informações entre as telas de aplicativos.
    3. Organização da interface do usuário.
    4. Metáforas avançadas da interface do usuário.
Prithiv Dharmaraj
fonte
0

Um fragmento vive dentro de uma atividade, enquanto uma atividade vive por si só.

superkytoz
fonte
6
"em si"? Talvez "por conta própria"? Ou "por si só"?
Peter Mortensen