Zakończenie bieżącej aktywności od fragmentu


96

Mam fragment w działaniu, którego używam jako szuflady nawigacji. Zawiera przyciski, które po kliknięciu uruchamiają nowe działania (startActivity z fragmentu po prostu wywołuje startActivity na bieżącej aktywności).

Przez całe życie nie potrafię pojąć, jak zakończę obecną działalność po rozpoczęciu nowej.

Szukam czegoś takiego we fragmencie:

@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();
    } 
}

Ale wydaje się, że Fragment.class nie implementuje finish () (tak jak implementuje startActivity (...)).

Chciałbym, aby backstack aktywności został wyczyszczony po uruchomieniu drugiej aktywności. (więc wycofanie się z nowej czynności technicznie spowodowałoby przeniesienie ich z powrotem do programu uruchamiającego)

Odpowiedzi:


281

Podczas pracy z fragmentami, zamiast używać thiskontekstu lub odwoływać się do niego, zawsze używaj getActivity(). Powinieneś zadzwonić

getActivity().finish();

aby zakończyć swoją działalność od fragmentu.


12
getActivity()może być nullw niektórych przypadkach. Co wtedy powinniśmy zrobić?
Matjaz Kristl

3
@ user983956 W takich przypadkach aktywność jest już zniszczona, więc po prostu nie dzwoń finish.
Cristian

2
Wskazówka: getActivity może mieć wartość null, jeśli spróbujesz go użyć przed zawyżeniem widoku
csanonymus

1
Działanie powinno być kontrolerem / ładowaniem, a nie fragmentem, powinieneś raczej wywołać działanie za pomocą interfejsu wywołania zwrotnego i pozwolić, aby działanie zdecydowało, czy powinno się zakończyć.
Ahmed,

1
Ponadto, jeśli masz wstrzyknięte w działaniu singletony, nie zapomnij ich zniszczyć, spowoduje to wycieki pamięci lub jeśli są wywołania zwrotne, usuń je, np. , if (getActivity ()! = null) {getActivity (). removeCallbacks (); getActivity (). zniszcz (); }
omersem

26

Cóż, właściwie ...

Nie chciałbym, żeby Fragment próbował zakończyć Ćwiczenie. Moim zdaniem to nadaje temu fragmentowi zbyt dużą władzę. Zamiast tego skorzystałbym z przewodnika tutaj: http://developer.android.com/training/basics/fragments/communicating.html

Niech fragment zdefiniuje interfejs, który musi zaimplementować działanie. Nawiąż połączenie z działaniem, a następnie pozwól, aby działanie zdecydowało, co zrobić z informacjami. Jeśli czynność chce się sama zakończyć, to może.


2
To dobra uwaga, ponieważ jedno działanie może mieć wiele fragmentów. Jak wspomniałeś, preferowanym sposobem komunikowania się fragmentu z powrotem do jego aktywności jest interfejs.
Sasquatch

11

Jak wspomniał Jon F Hancock , w ten sposób fragment może „zamknąć” czynność, sugerując jej zamknięcie. To sprawia, że ​​fragment jest przenośny, ponieważ jest tego powodem. Jeśli używasz go w innym działaniu, możesz nie chcieć go zamykać.

Poniższy kod to fragment działania i fragment z przyciskiem Zapisz i Anuluj.

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, który zawiera interfejs, który musi zaimplementować działanie wywołujące.

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

Za każdym razem, gdy zamykam fragment zakończeniem, cała czynność się zamyka. Według dokumentów fragmenty powinny pozostać tak długo, jak długo trwa aktywność rodziców.

Zamiast tego stwierdziłem, że mogę zmienić widoki z powrotem do działania nadrzędnego za pomocą tej instrukcji: setContentView (R.layout.activity_main);

To wraca z powrotem do rodzicielskiej aktywności.

Mam nadzieję, że pomoże to komuś, kto może tego szukać.


1

Bardzo prosty...

1- Po prostu złap aktywność getActivity()we fragmencie

2- wtedy zadzwoń finish();

Więc po prostu getActivity().finish();skończę działalność rodzicielską.


1

Należy użyć metody getActivity (), aby zakończyć działanie z fragmentu.

getActivity().finish();

1

We fragmentach użyj metody getActivity.finishAffinity ()

getActivity().finishAffinity();

Spowoduje to usunięcie całego fragmentu, który został wypchnięty przez bieżącą aktywność ze stosu z działaniem również ...


finishAffinity () usunie wszystkie działania, które mają to samo powinowactwo, więc działania poniżej bieżącej aktywności, która zawiera fragment na stosie, również mogą zostać zakończone.
Zakaria M. Jawas

0

Spróbuj tego. Nie powinno być żadnego ostrzeżenia ...

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

0

15 czerwca 2020 - zaktualizowana odpowiedź.

Masz dwie opcje dla Java i Kotlin. Jednak logika obu sposobów jest taka sama. Należy wywołać aktywność po wywołaniu metody finish () .

Odpowiedź dla Kotlina ,

Jeśli Twoja aktywność nie może być zerowa, użyj Answer_1 . Jeśli jednak twoja aktywność może być zerowa , użyj Answer_2 .

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

Odpowiedź dla Java,

getActivity().finish();

@canerkaseler


-1

spróbuj tego użyć

tak Fragment.classnie realizujefinish()

Podczas pracy z fragmentami, zamiast używać tego lub odwoływać się do kontekstu, zawsze używaj getActivity(). Powinieneś zadzwonić


11
Powiedz mi, jaka jest różnica między Twoją odpowiedzią a pierwszą odpowiedzią powyżej (autor: @ coder_For_Life22) ...
Filipe Brito

dont its a trap
Demotivated
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.