Завершение текущей активности из фрагмента

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 (...)).

Я хотел бы, чтобы backstack активности был очищен, когда они запускают 2-е действие. (так что при возврате из нового действия технически они вернутся обратно в средство запуска)

NPike
источник

Ответы:

281

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

getActivity().finish();

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

coder_For_Life22
источник
12
getActivity()может быть nullв некоторых случаях. Что нам тогда делать?
Matjaz Kristl
3
@ user983956 В таких случаях активность уже уничтожена, поэтому просто не звоните finish.
Кристиан
2
Подсказка: getActivity может иметь значение null, если вы попытаетесь использовать его до
расширения
1
Действие должно быть контроллером / зарядкой, а не фрагментом, вам лучше выполнить обратный вызов Activity через интерфейс обратного вызова и позволить Activity решить, следует ли ему завершить себя.
Ахмед
1
Кроме того, если у вас есть синглтоны, введенные в действие, не забудьте их уничтожить, это приведет к утечкам памяти или, если есть обратные вызовы, удалите их, т.е. , если (getActivity ()! = null) {getActivity (). removeCallbacks (); getActivity (). destroy (); }
omersem 05
26

А на самом деле...

Я бы не хотел, чтобы фрагмент пытался завершить действие. На мой взгляд, это придает Фрагменту слишком большой авторитет. Вместо этого я бы использовал руководство здесь: http://developer.android.com/training/basics/fragments/communicating.html

Пусть Фрагмент определит интерфейс, который должно реализовывать действие. Вызовите Activity, а затем пусть Activity решит, что делать с информацией. Если деятельность хочет закончить сама себя, то может.

Джон Ф. Хэнкок
источник
2
Это хороший момент, поскольку в одном действии может присутствовать несколько фрагментов. Как вы упомянули, предпочтительный способ обратной связи фрагмента с его активностью - через интерфейс.
Sasquatch
11

Как упоминал Джон Ф. Хэнкок , таким образом фрагмент может «закрыть» действие, предлагая закрыть действие. Это делает фрагмент переносимым, как и причина для них. Если вы используете его в другом действии, возможно, вы не захотите закрывать действие.

Код ниже - это отрывок из действия и фрагмент, в котором есть кнопки сохранения и отмены.

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, содержащий интерфейс, который необходимо реализовать для вызывающего действия.

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
   }
}
Sasquatch
источник
1

Каждый раз, когда я использую finish, чтобы закрыть фрагмент, вся активность закрывается. Согласно документации, фрагменты должны оставаться, пока сохраняется родительская активность.

Вместо этого я обнаружил, что могу изменить представление родительского действия с помощью этого оператора: setContentView (R.layout.activity_main);

Это возвращает меня к родительской деятельности.

Я надеюсь, что это поможет кому-то еще, кто может это искать.

Дэйв Кокс
источник
1

Очень просто...

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

2- затем позвоните finish();

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

Али Наваз
источник
1

Вы должны использовать метод getActivity (), чтобы завершить действие из фрагмента.

getActivity().finish();
Мадху Джаярама
источник
1

Во фрагменте используйте getActivity.finishAffinity ()

getActivity().finishAffinity();

Он также удалит весь фрагмент, который был выдвинут текущим действием, из стека с действием ...

Тусиф Акрам
источник
finishAffinity () удалит все действия с одинаковым сродством, поэтому действия ниже текущего действия, содержащего фрагмент в стеке, также могут быть завершены.
Закария М. Джавас
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 . Однако, если ваша активность может быть нулевой , используйте Ответ_2 .

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

Ответ для Java,

getActivity().finish();

@canerkaseler

Canerkaseler
источник
-1

попробуй использовать это

да Fragment.classне реализуетfinish()

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

Рахул Госвами
источник
11
Скажите мне разницу между вашим ответом и первым ответом выше (@ coder_For_Life22) ...
Филипе Брито
не ловушка
Демотивирован