Завершення поточної діяльності з фрагмента


96

У мене є фрагмент діяльності, який я використовую як шухляду навігації. Він містить кнопки, які при натисканні запускають нові дії (startActivity з фрагмента просто викликає startActivity для поточної активності).

За своє життя я не можу зрозуміти, як би я закінчив поточну діяльність після початку нової.

Я прагну досягти чогось такого у фрагменті:

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

Але, схоже, Fragment.class не реалізує finish () (як він реалізує startActivity (...)).

Я хотів би, щоб задниця активності була очищена, коли вони запускають 2-ю діяльність. (отже, натискання на нову діяльність технічно поверне їх назад до панелі запуску)

Відповіді:


277

Під час роботи з фрагментами, замість використання thisабо посилання на контекст, завжди використовуйте getActivity(). Вам слід зателефонувати

getActivity().finish();

щоб закінчити свою діяльність з фрагмента.


12
getActivity()може бути nullв деяких випадках. Що нам тоді робити?
Matjaz Kristl

3
@ user983956 У таких випадках активність вже знищена, тому просто не телефонуйте finish.
Крістіан

2
Як підказка: getActivity може бути нульовим, якщо ви спробуєте використати його перед надуванням подання
csanonymus

1
Діяльність повинна бути контролером / зарядом, а не фрагментом, вам краще скористатися зворотним викликом Діяльності через інтерфейс зворотного виклику і дозволити Активі вирішити, чи слід самому закінчувати.
Ахмед

1
Крім того, якщо у вас введені одиночні операції, не забудьте їх знищити, це призведе до витоків пам'яті або, якщо є зворотні виклики, видаліть їх, тобто. , if (getActivity ()! = null) {getActivity (). removeCallbacks (); getActivity (). знищити (); }
omersem

26

Ну насправді ...

Я б не хотів, щоб Фрагмент намагався закінчити Діяльність. Це, на мою думку, надає занадто багато авторитету Фрагменту. Натомість я б скористався путівником тут: http://developer.android.com/training/basics/fragments/communicating.html

Нехай Фрагмент визначає інтерфейс, який має реалізовувати Діяльність. Зателефонуйте до Діяльності, а потім нехай Діяльність вирішить, що робити з інформацією. Якщо діяльність хоче закінчити сама, тоді вона може.


2
Це хороший момент, оскільки в одній діяльності можуть бути присутніми кілька фрагментів. Як ви вже згадували, кращий спосіб, щоб фрагмент повідомляв про свою активність, - це інтерфейс.
Саскуач

11

Як згадував Джон Ф. Хенкок , саме так фрагмент може "закрити" діяльність, пропонуючи активність закрити. Це робить фрагмент портативним, що і є причиною для них. Якщо ви використовуєте його в іншій діяльності, можливо, ви не захочете закривати її.

Нижче наведений фрагмент дії та фрагмента, який має кнопку збереження та скасування.

Активність гравця

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, який містить інтерфейс, який має реалізувати виклична діяльність.

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

Кожного разу, коли я використовую фініш, щоб закрити фрагмент, вся діяльність закривається. Згідно з документами, фрагменти повинні залишатися до тих пір, поки залишається батьківська діяльність.

Натомість я виявив, що можу змінити подання батьківської активності за допомогою цього виразу: setContentView (R.layout.activity_main);

Це повертає мене до батьківської діяльності.

Я сподіваюся, що це допомагає комусь іншому, хто може це шукати.


1

Дуже просто...

1- просто захопіть активність getActivity()у фрагменті

2- потім зателефонуйте finish();

Тож просто getActivity().finish();закінчить батьківську діяльність.



1

У фрагменті використовуйте getActivity.finishAffinity ()

getActivity().finishAffinity();

Він також видалить весь фрагмент, який штовхає поточна активність, зі стеку разом із активністю ...


finishAffinity () видалить усі дії, що мають однакову спорідненість, тому дії нижче поточної активності, яка містить фрагмент у стеку, також можуть бути закінчені.
Zakaria M. Jawas

0

Спробуйте це. Попередження не повинно бути ...

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

0

15 червня 2020 р. - оновлена ​​відповідь.

У вас є два варіанти Java і Kotlin. Однак логіка обох шляхів однакова. Вам слід зателефонувати активність після виклику методу finish () .

Відповідь для Котліна ,

Якщо ваша активність не може бути нульовою, використовуйте Answer_1 . Однак, якщо ваша активність може бути нульовою , використовуйте Answer_2 .

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

Відповідь для Java,

getActivity().finish();

@canerkaseler


-1

спробуйте використати це

так Fragment.class не реалізуєfinish()

Під час роботи з фрагментами, замість використання цього або посилання на контекст, завжди використовуйте getActivity(). Вам слід зателефонувати


11
Скажіть мені різницю між вашою відповіддю та першою відповіддю вище (@ coder_For_Life22) ...
Філіпе Бріто

не пастка
Демотивований
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.