Qual é a diferença entre FragmentPagerAdapter
e FragmentStatePagerAdapter
?
Sobre FragmentPagerAdapter
o guia do Google diz:
Esta versão do pager é melhor para uso quando há um punhado de fragmentos estáticos tipicamente mais para serem paginados, como um conjunto de guias. O fragmento de cada página visitada pelo usuário será mantido na memória, embora sua hierarquia de exibição possa ser destruída quando não estiver visível. Isso pode resultar no uso de uma quantidade significativa de memória, pois as instâncias de fragmento podem manter uma quantidade arbitrária de estado. Para conjuntos maiores de páginas, considere
FragmentStatePagerAdapter
.
E sobre FragmentStatePagerAdapter
:
Essa versão do pager é mais útil quando há um grande número de páginas, funcionando mais como uma exibição de lista. Quando as páginas não estão visíveis para o usuário, seu fragmento inteiro pode ser destruído, mantendo apenas o estado salvo desse fragmento. Isso permite que o pager mantenha muito menos memória associada a cada página visitada em comparação com
FragmentPagerAdapter
o custo de potencialmente mais sobrecarga ao alternar entre as páginas.
Então, eu tenho apenas 3 fragmentos. Mas todos eles são módulos separados com uma grande quantidade de dados.
Fragment1
lida com alguns dados (nos quais os usuários inserem) e os passa por atividade Fragment2
, o que é simples ListFragment
. Fragment3
também é um ListFragment
.
Então, minhas perguntas são : Qual adaptador devo usar? FragmentPagerAdapter
ou FragmentStatePagerAdapter
?
fonte
FragmentPagerAdapter
eFragmentStatePagerAdapter
mas o que éFragmentStateAdapter
?Respostas:
Como dizem os médicos, pense dessa maneira. Se você fosse fazer um aplicativo como um leitor de livros, não desejaria carregar todos os fragmentos na memória de uma só vez. Você gostaria de carregar e destruir
Fragments
enquanto o usuário lê. Nesse caso, você usaráFragmentStatePagerAdapter
. Se você está apenas exibindo 3 "guias" que não contêm muitos dados pesados (comoBitmaps
),FragmentPagerAdapter
pode ser bom para você. Além disso, lembre-se de que,ViewPager
por padrão, carregará 3 fragmentos na memória. O primeiro queAdapter
você mencionar pode destruir aView
hierarquia e recarregá-lo quando necessário, o segundoAdapter
salva apenas o estado doFragment
e o destrói completamente; se o usuário voltar a essa página, o estado será recuperado.fonte
FragmentPagerAdapter
usá-lo.FragmentPagerAdapter
é que a alternância entre fragmentos pode ser muito mais rápida, pois osFragment
objetos reais não precisam ser reconstruídos a cada vez. Por outro lado, isso acabaria usando mais memória mantendo os objetos de fragmento na memória.viewPager.setOffscreenPageLimit(2)
.FragmentPagerAdapter
armazena todo o fragmento na memória e pode aumentar a sobrecarga da memória se uma grande quantidade de fragmentos for usadaViewPager
.Ao contrário de seu irmão,
FragmentStatePagerAdapter
apenas armazena oStInstanceState dos fragmentos e destrói todos os fragmentos quando eles perdem o foco.Portanto,
FragmentStatePagerAdapter
deve ser usado quando tivermos que usar fragmentos dinâmicos, como fragmentos com widgets, pois seus dados podem ser armazenados no arquivosavedInstanceState
.Também não afetará o desempenho, mesmo que haja um grande número de fragmentos.Pelo contrário, seu irmão
FragmentPagerAdapter
deve ser usado quando precisamos armazenar todo o fragmento na memória.Quando digo que todo o fragmento é mantido na memória, suas instâncias não serão destruídas e criariam uma sobrecarga de memória. Portanto, é recomendável usar
FragmentPagerAdapter
somente quando houver um número baixo de fragmentosViewPager
.Seria ainda melhor se os fragmentos fossem estáticos, pois não estariam tendo grande quantidade de objetos cujas instâncias seriam armazenadas.
Para ser mais detalhado,
FragmentStatePagerAdapter:
com
FragmentStatePagerAdapter
, seu fragmento desnecessário é destruído. Uma transação é comprometida para remover completamente o fragmento da sua atividadeFragmentManager
.O estado
FragmentStatePagerAdapter
vem do fato de que ele salvará o seu fragmentoBundle
desavedInstanceState
quando é destruído. Quando o usuário voltar, o novo fragmento será restaurado usando o estado do fragmento.FragmentPagerAdapter:
Por comparação
FragmentPagerAdapter
, nada é do tipo. Quando o fragmento não é mais necessário.FragmentPagerAdapter
chamadetach(Fragment)
a transação em vez deremove(Fragment)
.Isso destrói a visão do fragmento, mas deixa viva a instância do fragmento no
FragmentManager
. Para que os fragmentos criados noFragmentPagerAdapter
nunca sejam destruídos.fonte
Aqui está um ciclo de vida de log de cada fragmento no
ViewPager
qual possui 4 fragmentos eoffscreenPageLimit = 1 (default value)
FragmentStatePagerAdapter
Vá para o Fragmento1 (atividade de lançamento)
Ir para Fragment2
Ir para Fragment3
Ir para Fragment4
FragmentPagerAdapter
Vá para o Fragmento1 (atividade de lançamento)
Ir para Fragment2
Ir para Fragment3
Ir para Fragment4
Conclusão :
FragmentStatePagerAdapter
chamaonDestroy
quando o fragmento é superadooffscreenPageLimit
enquantoFragmentPagerAdapter
não.Nota : Eu acho que devemos usar
FragmentStatePagerAdapter
para umViewPager
que tenha muitas páginas, porque será bom para o desempenho.Exemplo de
offscreenPageLimit
:Se formos para Fragment3, ele vai Detroy Fragment1 (ou Fragment5 se tem) porque
offscreenPageLimit = 1
. Se definirmosoffscreenPageLimit > 1
, não destruirá.Se neste exemplo, definirmos
offscreenPageLimit=4
, não haverá diferença entre usarFragmentStatePagerAdapter
ouFragmentPagerAdapter
porque o Fragment nunca chamaonDestroyView
eonDestroy
quando alteramos a guiaDemonstração do Github aqui
fonte
Algo que não é explicitamente dito na documentação ou nas respostas nesta página (mesmo que implícitas pelo @Naruto), é que
FragmentPagerAdapter
não atualizará os Fragmentos se os dados no Fragmento mudarem, pois mantém o Fragmento na memória.Portanto, mesmo se você tiver um número limitado de fragmentos para exibir, se desejar atualizar seus fragmentos (por exemplo, execute novamente a consulta para atualizar o listView no fragmento), será necessário usar FragmentStatePagerAdapter.
Meu argumento aqui é que o número de fragmentos e se são ou não semelhantes nem sempre é o aspecto principal a considerar. Se seus fragmentos são dinâmicos ou não, também é fundamental.
fonte
FragmentPagerAdapter
em minha atividade que usa um ViewPager para mostrar dois fragmentos - onde cada fragmento contém uma lista. Minha primeira lista é chamada "Todos os relatórios" e a segunda lista é "Relatórios favoritos". Na primeira lista, se eu tocar no ícone de estrela de um relatório, ele atualizará o banco de dados para alternar o status favorito desse relatório. Depois deslizo e vejo esse relatório com sucesso na interface da segunda lista. Portanto, talvez as instâncias sejam mantidas na memória, mas em alguns casos (por exemplo, o meu), o conteúdo será realmente atualizado corretamente para FragmentPagerAdapterFragmentPagerAdapter
armazena os dados anteriores que são buscados no adaptador eFragmentStatePagerAdapter
obtém o novo valor do adaptador toda vez que ele é executado.fonte
FragmentStatePagerAdapter = Para acomodar um grande número de fragmentos no ViewPager. Como esse adaptador destrói o fragmento quando ele não está visível para o usuário e apenas o SaveInstanceState do fragmento é mantido para uso posterior. Dessa forma, uma baixa quantidade de memória é usada e um melhor desempenho é entregue no caso de fragmentos dinâmicos.
fonte
FragmentPagerAdapter : o fragmento de cada página visitada pelo usuário será armazenado na memória, embora a exibição seja destruída. Portanto, quando a página estiver visível novamente, a exibição será recriada, mas a instância do fragmento não será recriada. Isso pode resultar em uma quantidade significativa de memória sendo usada. FragmentPagerAdapter deve ser usado quando precisamos armazenar o fragmento inteiro na memória. Chama FragmentPagerAdapter desanexar (fragmento) na transação em vez de remover (fragmento).
FragmentStatePagerAdapter : a instância do fragmento é destruída quando não está visível para o Usuário, exceto o estado salvo do fragmento. Isso resulta no uso de apenas uma pequena quantidade de memória e pode ser útil para manipular conjuntos de dados maiores. Deve ser usado quando precisamos usar fragmentos dinâmicos, como fragmentos com widgets, pois seus dados podem ser armazenados no saveInstanceState. Além disso, não afetará o desempenho, mesmo que haja um grande número de fragmentos.
fonte