Concluindo a atividade atual de um fragmento


96

Tenho um fragmento em uma atividade que estou usando como gaveta de navegação. Ele contém botões que, quando clicados, iniciam novas atividades (startActivity a partir de um fragmento simplesmente chama startActivity na atividade atual).

Pela minha vida, não consigo descobrir como terminaria a atividade atual depois de começar uma nova.

Estou procurando conseguir algo assim no fragmento:

@Override
public void onClick(View view) {
    // TODO Auto-generated method stub
    if (view == mButtonShows) {
        Intent intent = new Intent(view.getContext(), MyNewActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
        finish();
    } 
}

Mas parece que Fragment.class não implementa finish () (como implementa startActivity (...)).

Gostaria que o backstack de atividades fosse apagado quando eles iniciarem a 2ª atividade. (então, pressionar de volta para a nova atividade iria tecnicamente levá-los de volta ao iniciador)

Respostas:


277

Ao trabalhar com fragmentos, em vez de usar thisou referir-se ao contexto, use sempre getActivity(). Você deveria ligar

getActivity().finish();

para terminar sua atividade do fragmento.


12
getActivity()pode ser nullem alguns casos. O que nós devemos fazer então?
Matjaz Kristl

3
@ user983956 Nesses casos, a atividade já está destruída, então não ligue finish.
Cristian

2
Como dica: getActivity pode ser nulo se você tentar usá-lo antes de aumentar a exibição
csanonymus

1
A Activity deve ser o controlador / encarregado, não o fragmento, você deve, em vez disso, fazer um callback da Activity através de uma interface de callback e deixar que a Activity decida se deve terminar sozinha.
Ahmed

1
Além disso, se você tiver singletons injetados na atividade, não se esqueça de destruí-los, isso criará vazamentos de memória ou, se houver retornos de chamada, remova-os, ou seja. , if (getActivity ()! = null) {getActivity (). removeCallbacks (); getActivity (). destroy (); }
omersem

26

Bem, na verdade...

Eu não faria com que o Fragmento tentasse terminar a Atividade. Isso confere muita autoridade ao Fragmento, na minha opinião. Em vez disso, eu usaria o guia aqui: http://developer.android.com/training/basics/fragments/communicating.html

Faça com que o Fragment defina uma interface que a Activity deve implementar. Faça uma chamada para a Activity e deixe que a Activity decida o que fazer com as informações. Se a atividade quiser terminar sozinha, ela pode.


2
Esse é um bom ponto, pois uma única atividade pode ter vários fragmentos presentes. Como você mencionou, a maneira preferencial de um fragmento se comunicar com sua atividade é por meio de uma interface.
Sasquatch

11

Conforme mencionado por Jon F Hancock , é assim que um fragmento pode 'fechar' a atividade, sugerindo que ela seja fechada. Isso torna o fragmento portátil, pois é a razão para eles. Se você usá-lo em uma atividade diferente, pode não querer fechar a atividade.

O código abaixo é um trecho de uma atividade e fragmento que tem um botão Salvar e Cancelar.

PlayerActivity

public class PlayerActivity extends Activity 
    implements PlayerInfo.PlayerAddListener {

    public void onPlayerCancel() {
       // Decide if its suitable to close the activity, 
       //e.g. is an edit being done in one of the other fragments?
       finish();
    }
}

PlayerInfoFragment, que contém uma interface que a atividade de chamada precisa implementar.

public class PlayerInfoFragment extends Fragment {
   private PlayerAddListener callback; // implemented in the Activity

   @Override
   public void onAttach(Activity activity) {
     super.onAttach(activity);
     callback= (PlayerAddListener) activity;
   }

   public interface PlayerAddListener {
       public void onPlayerSave(Player p); // not shown in impl above
       public void onPlayerCancel();
   }

   public void btnCancel(View v) {
      callback.onPlayerCancel(); // the activity's implementation
   }
}

1

Cada vez que uso terminar para fechar o fragmento, toda a atividade fecha. De acordo com os documentos, os fragmentos devem permanecer enquanto a atividade pai permanecer.

Em vez disso, descobri que posso alterar as visualizações da atividade pai usando esta instrução: setContentView (R.layout.activity_main);

Isso me leva de volta à atividade dos pais.

Espero que isso ajude alguém que possa estar procurando por isso.


1

Muito simples...

1- apenas pegue a atividade getActivity()no fragmento

2- então ligue finish();

Então, só getActivity().finish();vai terminar a atividade dos pais.


1

Você deve usar o método getActivity () a fim de terminar a atividade do fragmento.

getActivity().finish();

1

Em Fragment, use getActivity.finishAffinity ()

getActivity().finishAffinity();

Ele removerá todos os fragmentos que foram enviados pela atividade atual da Pilha com a Atividade também ...


finishAffinity () irá remover todas as atividades que têm a mesma afinidade, então as atividades abaixo da atividade atual que contém o fragmento na pilha também podem ser concluídas.
Zakaria M. Jawas

0

Experimente isso. Não deve haver nenhum aviso ...

            Activity thisActivity = getActivity();
            if (thisActivity != null) {
                startActivity(new Intent(thisActivity, yourActivity.class)); // if needed
                thisActivity.finish();
            }

0

15 de junho de 2020 - Resposta atualizada.

Você tem duas opções para Java e Kotlin. No entanto, a lógica de ambas as maneiras é a mesma. Você deve chamar a atividade após a chamada do método terminar () .

Resposta para Kotlin ,

Se sua atividade não pode ser nula, use Answer_1 . No entanto, se sua atividade pode ser nula , use Answer_2 .

Answer_1: activity!!.finish()
Answer_2: activity?.finish()

Resposta para Java,

getActivity().finish();

@canerkaseler


-1

tente usar isso

sim Fragment.classnão implementafinish()

Ao trabalhar com fragmentos, em vez de usar isso ou se referir ao contexto, sempre use getActivity(). Você deveria ligar


11
Diga-me a diferença entre a sua resposta e a primeira resposta acima (por @ coder_For_Life22) ...
Filipe Brito

não é uma armadilha
Desmotivado em
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.