Estou aprendendo a usar fragmentos. Eu tenho três instâncias Fragment
que são inicializadas na parte superior da classe. Estou adicionando o fragmento a uma atividade como esta:
Declarando e inicializando:
Fragment A = new AFragment();
Fragment B = new BFragment();
Fragment C = new CFragment();
Substituindo / Adicionando:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, A);
ft.addToBackStack(null);
ft.commit();
Esses trechos estão funcionando corretamente. Cada fragmento é anexado à atividade e é salvo na pilha traseira sem nenhum problema.
Então, quando eu lançar A
, C
e em seguida B
, os olhares pilha como este:
| |
|B|
|C|
|A|
___
E quando pressiono o botão 'voltar', B
é destruído e C
retomado.
Mas, quando inicio o fragmento A
pela segunda vez, em vez de retomar da pilha traseira, ele é adicionado na parte superior da pilha traseira
| |
|A|
|C|
|A|
___
Mas quero retomar A
e destruir todos os fragmentos em cima (se houver). Na verdade, eu apenas gosto do comportamento padrão da pilha traseira.
Como eu faço isso?
Esperado: ( A
deve ser retomado e os principais fragmentos devem ser destruídos)
| |
| |
| |
|A|
___
Editar: (sugerido por A - C)
Este é o meu código de tentativa:
private void selectItem(int position) {
Fragment problemSearch = null, problemStatistics = null;
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
String backStateName = null;
Fragment fragmentName = null;
boolean fragmentPopped = false;
switch (position) {
case 0:
fragmentName = profile;
break;
case 1:
fragmentName = submissionStatistics;
break;
case 2:
fragmentName = solvedProblemLevel;
break;
case 3:
fragmentName = latestSubmissions;
break;
case 4:
fragmentName = CPExercise;
break;
case 5:
Bundle bundle = new Bundle();
bundle.putInt("problem_no", problemNo);
problemSearch = new ProblemWebView();
problemSearch.setArguments(bundle);
fragmentName = problemSearch;
break;
case 6:
fragmentName = rankList;
break;
case 7:
fragmentName = liveSubmissions;
break;
case 8:
Bundle bundles = new Bundle();
bundles.putInt("problem_no", problemNo);
problemStatistics = new ProblemStatistics();
problemStatistics.setArguments(bundles);
fragmentName = problemStatistics;
default:
break;
}
backStateName = fragmentName.getClass().getName();
fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
ft.replace(R.id.content_frame, fragmentName);
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(backStateName);
ft.commit();
// I am using drawer layout
mDrawerList.setItemChecked(position, true);
setTitle(title[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
O problema é que, quando inicio A
e B
, em seguida, pressiono 'voltar', B
é removido e A
retomado. e pressionar 'voltar' uma segunda vez deve sair do aplicativo. Mas está mostrando uma janela em branco e eu tenho que pressionar uma terceira vez para fechá-la.
Além disso, quando inicio A
, então B
, então C
, B
novamente ...
Esperado:
| |
| |
|B|
|A|
___
Real:
| |
|B|
|B|
|A|
___
Devo substituir onBackPressed()
qualquer personalização ou estou perdendo alguma coisa?
fonte
OnBackstackChangedListener
para que você possa garantir que está lidando com o fragmento correto.OnBackstackChangedListener
mesmo.instanceof
:)A-B-C-B
e pressione uma vez, você voltaráA
e não voltaráC
. Isso ocorre porquepopBackStackImmediate
não apenas aparece a tag fornecida, mas também tudo acima. Existe algum trabalho por aí?Penso que este método pode resolver o seu problema:
publicado originalmente nesta pergunta
fonte
Etapa 1: implemente uma interface com sua classe de atividade
Etapa 2: quando você chamar o outro fragmento, adicione este método:
fonte
fonte
fonte
Solução mais fácil mudará essa linha
ft.replace(R.id.content_frame, A);
paraft.add(R.id.content_frame, A);
E dentro do seu layout XML, use
Clickable
significa que ele pode ser clicado por um dispositivo apontador ou toque em um dispositivo de toque.Focusable
significa que ele pode obter o foco de um dispositivo de entrada como um teclado. Dispositivos de entrada, como teclados, não podem decidir para qual exibição enviar seus eventos de entrada com base nas próprias entradas; portanto, eles os enviam para a exibição em foco.fonte