Várias operações do sistema Android podem afetar o estado do fragmento. Para garantir que o estado do usuário seja salvo, o framework do Android salva e restaura automaticamente os fragmentos e a pilha de retorno. Portanto, você precisa garantir que todos os dados do seu fragmento também sejam salvos e restaurados.
A tabela a seguir descreve as operações que fazem com que o fragmento perca o estado e se os vários tipos de estado persistem com essas mudanças. Os tipos de estado mencionados na tabela são os seguintes:
- Variáveis: variáveis locais no fragmento.
- Estado da visualização: qualquer dado pertencente a uma ou mais visualizações no fragmento.
- SavedState: dados inerentes a essa instância de fragmento que precisam ser salvos
em
onSaveInstanceState()
. - NonConfig: dados extraídos de uma fonte externa, como um servidor ou repositório local, ou dados criados pelo usuário que são enviados a um servidor após a confirmação.
Muitas vezes, as variáveis são tratadas da mesma forma que SavedState, mas a tabela a seguir distingue entre os dois para demonstrar o efeito das várias operações em cada um.
Operação | Variáveis | Estado da visualização | SavedState | NonConfig |
---|---|---|---|---|
Adicionado à pilha de retorno | ✓ | ✓ | x | ✓ |
Mudança de configuração | x | ✓ | ✓ | ✓ |
Interrupção/recriação de processos | x | ✓ | ✓ | ✓* |
Removido e não adicionado à backstack | x | x | x | x |
Host concluído | x | x | x | x |
* O estado NonConfig pode ser retido durante o encerramento do processo usando o módulo Saved State para ViewModel.
Tabela 1: várias operações destrutivas de fragmentos e os efeitos que elas têm em diferentes tipos de estado.
Vejamos um exemplo específico. Imagine uma tela que gera uma
string aleatória, exibindo-a em uma TextView
e oferecendo uma opção para editar
a string antes de enviá-la a um amigo:

Para esse exemplo, suponha que, quando o usuário pressionar o botão de edição, o
app exibirá uma visualização EditText
, em que o usuário poderá editar a mensagem. Se o
usuário clicar em CANCELAR, a visualização EditText
será removida, e a
visibilidade será definida como View.GONE
. Essa
tela pode exigir o gerenciamento de quatro partes de dados para garantir uma experiência
perfeita:
Dados | Tipo | Tipo de estado | Descrição |
---|---|---|---|
seed |
Long |
NonConfig | Seed usada para gerar aleatoriamente uma nova boa ação. Gerada quando
o ViewModel é criado. |
randomGoodDeed |
String |
SavedState + variável | Gerado quando o fragmento é criado pela primeira vez.
A randomGoodDeed é salva para garantir que os usuários tenham acesso à
mesma boa ação aleatória até mesmo após o encerramento e
a recriação do processo. |
isEditing |
Boolean |
SavedState + variável | Sinalização booleana definida como true quando o usuário começa a editar.
isEditing é salvo para garantir que a parte de edição
da tela permaneça visível quando o fragmento é recriado. |
Texto editado | Editable |
Estado da visualização (propriedade de EditText ) |
O texto editado na visualização EditText .
A EditText salva esse texto para garantir que as mudanças
em andamento do usuário não sejam perdidas. |
Tabela 2: determina que o app gerador de texto aleatório precisa fazer o gerenciamento.
Nas seções a seguir, descrevemos como gerenciar corretamente o estado dos seus dados usando operações destrutivas.
Estado da visualização
As visualizações são responsáveis por gerenciar os próprios estados. Por exemplo, quando uma
visualização aceita entrada do usuário, é responsabilidade dela salvar e restaurar
essa entrada para processar as mudanças de configuração. Todas as visualizações fornecidas pelo framework do Android têm a própria implementação de onSaveInstanceState()
e
onRestoreInstanceState()
. Assim, você não precisa gerenciar o estado da visualização no
seu fragmento.
Por exemplo, no cenário anterior, a string editada é mantida em um
EditText
. Um EditText
sabe
o valor do texto que está sendo exibido, bem como outros detalhes, como
o início e o fim de qualquer texto selecionado.
Uma visualização precisa de um ID para reter o estado. Esse ID precisa ser exclusivo no fragmento e na hierarquia da visualização. Visualizações sem ID não podem reter o estado.
<EditText
android:id="@+id/good_deed_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Como mencionado na tabela 1, as visualizações salvam e restauram ViewState
usando
todas as operações que não removem o fragmento nem destroem o host.
SavedState
Seu fragmento é responsável por gerenciar pequenas quantidades de estado dinâmico
que são essenciais para as funções do fragmento. É possível reter
dados facilmente serializados usando
Fragment.onSaveInstanceState(Bundle)
.
De modo semelhante a
Activity.onSaveInstanceState(Bundle)
,
os dados que você coloca no pacote são retidos por mudanças de configuração
e processam o encerramento e a recriação, estando disponíveis nos métodos
onCreate(Bundle)
,
onCreateView(LayoutInflater, ViewGroup, Bundle)
e
onViewCreated(View, Bundle)
do fragmento.
Continuando com o exemplo anterior, randomGoodDeed
é a ação
exibida para o usuário, enquanto isEditing
é uma sinalização para determinar se o
fragmento exibe ou oculta o EditText
. Esse estado salvo precisa ser
mantido usando onSaveInstanceState(Bundle)
, conforme mostrado no exemplo
a seguir:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putBoolean(IS_EDITING_KEY, isEditing)
outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed)
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(IS_EDITING_KEY, isEditing);
outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed);
}
Para restaurar o estado em onCreate(Bundle)
, recupere o valor armazenado
do pacote:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false)
randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY)
?: viewModel.generateRandomGoodDeed()
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
isEditing = savedInstanceState.getBoolean(IS_EDITING_KEY, false);
randomGoodDeed = savedInstanceState.getString(RANDOM_GOOD_DEED_KEY);
} else {
randomGoodDeed = viewModel.generateRandomGoodDeed();
}
}
Como mencionado na tabela 1, as variáveis são retidas quando o fragmento é colocado na pilha de retorno. Tratá-las como estado salvo garante que elas persistam por todas as operações destrutivas.
NonConfig
Os dados de NonConfig precisam ser colocados fora do seu fragmento, como em
um ViewModel
. No exemplo
anterior, seed
(nosso estado NonConfig) é gerado no ViewModel
.
A lógica para manter o estado pertence ao ViewModel
.
public class RandomGoodDeedViewModel : ViewModel() {
private val seed = ... // Generate the seed
private fun generateRandomGoodDeed(): String {
val goodDeed = ... // Generate a random good deed using the seed
return goodDeed
}
}
public class RandomGoodDeedViewModel extends ViewModel {
private Long seed = ... // Generate the seed
private String generateRandomGoodDeed() {
String goodDeed = ... // Generate a random good deed using the seed
return goodDeed;
}
}
A classe ViewModel
permite inerentemente que os dados sobrevivam a mudanças de
configuração, como rotações de tela, e permaneçam na memória quando o
fragmento é colocado na pilha de retorno. Após o encerramento e a recriação do processo,
o ViewModel
é recriado, e uma nova seed
é gerada. A adição de um
módulo SavedState
ao ViewModel
permite que o ViewModel
retenha o estado simples após o
encerramento e a recriação do processo.
Outros recursos
Para ver mais informações sobre como gerenciar o estado de fragmentos, consulte os recursos a seguir.