从片段中完成当前活动

118

我在一个活动中使用了一个片段作为导航抽屉。它包含按钮,当点击时会启动新的活动(从片段中的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类没有实现finish()方法(就像它实现了startActivity(...)方法一样)。

当他们启动第二个活动时,我希望清除活动返回栈。(因此,从新活动按下返回键将在技术上使他们返回到启动器)

13个回答

337

在使用片段时,不要使用this或引用上下文,而应始终使用getActivity()。您应该调用:

Java

getActivity().finish();

Kotlin

activity.finish()

从fragment中结束您的activity。


14
在某些情况下,getActivity()可能为null。那么我们应该怎么办? - Matjaz Kristl
4
在这种情况下,活动已经被销毁了,因此不要调用“finish”。 - Cristian
2
作为提示:如果在填充视图之前尝试使用它,则getActivity可能为空。 - Daniel Bejan
4
应该由Activity作为控制器/负责人,而不是Fragment。你应该通过回调接口回调Activity,让Activity决定是否结束自身。 - Ahmed
1
此外,如果您在活动中注入了单例,请不要忘记销毁它们,否则会导致内存泄漏。或者,如果有回调,请将其删除,例如: if (getActivity() != null) { getActivity().removeCallbacks(); getActivity().destroy();
}
- omersem
显示剩余4条评论

30

实际上...

我认为不应该让Fragment去结束Activity,这会使Fragment的权限过大。相反,我将使用此处提供的指南:http://developer.android.com/training/basics/fragments/communicating.html

让Fragment定义一个接口,必须由Activity来实现。调用Activity,然后让Activity决定如何处理信息。如果Activity希望结束自身,则可以这样做。


2
这是一个很好的观点,因为单个活动可以有多个片段存在。正如您所提到的,片段与其活动进行通信的首选方式是通过接口。 - Sasquatch

13

Jon F Hancock所述,这就是一个片段如何通过建议该活动关闭来“关闭”活动。这使得片段具有可移植性,这也是它们存在的原因。如果您在另一个活动中使用它,则可能不希望关闭该活动。

下面的代码是活动和片段中带有保存和取消按钮的代码片段。

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
   }
}

6
这不需要断言,是Android JetPack中片段的最新更新。
requireActivity().finish();

5
你需要在Fragment中使用getActivity()方法来结束activity。
getActivity().finish();

3

在 Fragment 中 使用 getActivity.finishAffinity()。

getActivity().finishAffinity();

它将从堆栈中删除由当前Activity推送的所有片段,同时也会删除Activity本身...

finishAffinity() 将删除所有具有相同亲和性的活动,因此包含堆栈中片段的当前活动下面的活动也可能被结束。 - Zakaria M. Jawas

2
每次使用finish关闭片段时,整个活动都会关闭。根据文档,片段应该与父活动保持一致。
相反,我发现可以通过使用以下语句将视图更改回到父活动: setContentView(R.layout.activity_main);
这将把我带回到父活动。
希望这可以帮助其他可能正在寻找这个的人。

2

非常简单...

1- 只需在片段中使用 getActivity() 获取活动

2- 然后调用finish();

因此,只需使用getActivity().finish();即可完成父级活动。


0

简单的解决方案:

activity?.finish()

1
这个已经在2020年6月发布过了(https://dev59.com/3Gsz5IYBdhLWcg3wbHLF#62393957)。 - Chris

0

在 Fragment 中结束活动,请使用以下代码:

getActivity().finish();


2
这个问题已经有答案了。在回答旧问题时,只有当它们提供新的、独特的解决方案时才会发布。 - Abhishek Dutt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接