No android, um fragmento (digamos FragA
) é adicionado ao backstack e outro fragmento (digamos FragB
) chega ao topo. Agora, ao voltar, FragA
chega ao topo e onCreateView()
é chamado. Agora eu estava FragA
em um estado específico antes de FragB
ser empurrado para cima.
Minha pergunta é como posso restaurar FragA
para o estado anterior? Existe uma maneira de salvar o estado (como, por exemplo, em um pacote) e, em caso afirmativo, qual método devo substituir?
android
android-fragments
pankajagarwal
fonte
fonte
onSaveInstanceState
só é chamado quando a atividade correspondente também está sendo desligada.Os fragmentos
onSaveInstanceState(Bundle outState)
nunca serão chamados, a menos que a atividade do fragmento invoque a si mesma e os fragmentos anexados. Portanto, esse método não será chamado até que algo (normalmente rotação) force a atividadeSaveInstanceState
e a restaure posteriormente. Porém, se você tiver apenas uma atividade e um grande conjunto de fragmentos (com uso intensivo dereplace
) e o aplicativo for executado apenas em uma atividade de orientação,onSaveInstanceState(Bundle outState)
poderá não ser chamada por muito tempo.Conheço três soluções possíveis.
O primeiro:
use os argumentos do fragmento para armazenar dados importantes:
A segunda maneira, mas menos pedante - mantenha variáveis em singletons
O terceiro - não
replace()
fragmentos, masadd()
/show()
/hide()
eles.fonte
Fragment.onSaveInstanceState()
nunca foi chamado. Apenas salve seus próprios dados no argumento, incluindo os itens na exibição em lista ou apenas seus IDs (se você tiver outro gerenciador de dados centralizado). Não há necessidade de salvar a posição da exibição de lista - que foi salva e restaurada automaticamente.String persistentVariable = mySavedInstanceState.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
é semprenull
. Qual é o problema?getArguments()
é DEFINITIVAMENTE o caminho a seguir, incluindo fragmentos aninhados em um ViewPager. Uso 1 atividade e troco muitos fragmentos de entrada / saída, e isso funciona perfeitamente. Aqui está um teste simples para você examinar qualquer solução proposta: 1) vá do fragmento A para o fragmento B; 2) mude a orientação do dispositivo duas vezes; 3) pressione o botão voltar no dispositivo.setArguments(new Bundle());
substituiu o antigo pacote. Portanto, certifique-se de criar fragmento apenas uma vez e, em seguida, use esta instância em vez de criar uma nova sempre.Observe que, se você trabalha com fragmentos usando o ViewPager, é muito fácil. Você só precisa chamar esse método:
setOffscreenPageLimit()
.De acordo com os documentos:
Problema semelhante aqui
fonte
Basta inflar sua visualização pela primeira vez.
Exemplo a seguir:
}
fonte
Fragment
refere-se à sua visualização raiz não fará isso. Embora a referência por alguns elementos da raiz do GC , como propriedade estática global, variável de thread não-ui. UmaFragment
instância não é raiz da GC, portanto pode ser coletada como lixo. O mesmo acontecerá com sua visão raiz.Eu trabalhei com um problema muito parecido com isso. Como eu sabia que voltaria frequentemente a um fragmento anterior, verifiquei se o fragmento
.isAdded()
era verdadeiro e, se sim, em vez de fazer umtransaction.replace()
, apenas faço atransaction.show()
. Isso evita que o fragmento seja recriado se já estiver na pilha - não é necessário salvar o estado.Outra coisa a ter em mente é que, embora isso preserve a ordem natural dos fragmentos, você ainda precisará lidar com a atividade que está sendo destruída e recriada com a mudança de orientação (config). Para contornar isso no AndroidManifest.xml para o seu nó:
No Android 3.0 e superior, o
screenSize
é aparentemente necessário.Boa sorte
fonte
android:configChanges=everythinYouCanThinkOf|moreThingsYouFoundOnTheInternets
seu manifesto. Em vez disso, aprenda como salvar e restaurar o estado, por exemplo, aqui: speakerdeck.com/cyrilmottier/…A melhor solução que encontrei está abaixo:
onSavedInstanceState (): sempre chamado dentro do fragmento quando a atividade é encerrada (mova a atividade de um para outro ou as alterações de configuração). Portanto, se estivermos chamando vários fragmentos na mesma atividade, precisamos usar a seguinte abordagem:
Use OnDestroyView () do fragmento e salve o objeto inteiro dentro desse método. Em seguida, OnActivityCreated (): verifique se o objeto é nulo ou não (porque esse método chama sempre). Agora restaure o estado de um objeto aqui.
Funciona sempre!
fonte
se você estiver lidando com as alterações de configuração em sua atividade de fragmento especificada no manifesto do Android como esta
então o
onSaveInstanceState
fragmento não será chamado e osavedInstanceState
objeto sempre será nulo.fonte
Não acho que
onSaveInstanceState
seja uma boa solução. apenas use para atividades que foram destruídas.No Android 3.0, o Fragmen foi gerenciado pelo FragmentManager, a condição é: um mapeamento de atividade de manny fragmentos, quando o fragmento é adicionado (não substitua: será recriado) no backStack, a visualização será destruída. quando voltar ao último, ele será exibido como antes.
Então eu acho que o fragmentManger e a transação são bons o suficiente para lidar com isso.
fonte
Eu usei uma abordagem híbrida para fragmentos que contêm uma exibição de lista. Parece ter bom desempenho, já que não substituo o fragmento atual, mas adiciono o novo fragmento e oculto o atual. Eu tenho o seguinte método na atividade que hospeda meus fragmentos:
Eu uso esse método no meu fragmento (contendo a exibição de lista) sempre que um item da lista é clicado / tocado (e, portanto, preciso iniciar / exibir o fragmento de detalhes):
getFragmentTags()
retorna uma matriz de seqüências de caracteres que eu uso como tags para diferentes fragmentos quando adiciono um novo fragmento (consulte otransaction.add
método noaddFragment
método acima).No fragmento que contém a exibição de lista, faço isso no método onPause ():
Em seguida, no onCreateView do fragmento (na verdade, em um método que é chamado no onCreateView), restauro o estado:
fonte
No final, depois de tentar muitas dessas soluções complicadas, eu só precisava salvar / restaurar um único valor no meu Fragmento (o conteúdo de um EditText) e, apesar de não ser a solução mais elegante, criar uma SharedPreference e armazenar meu estado trabalhou para mim
fonte
Uma maneira simples de manter os valores dos campos em diferentes fragmentos em uma atividade
Crie as instâncias de fragmentos e adicione em vez de substituir e remover
Em seguida, apenas mostre e oculte os fragmentos em vez de adicioná-los e removê-los novamente
;
fonte
fonte