从片段完成当前活动


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(...)一样)。

我希望在他们启动第二项活动时清除活动堆栈。(因此,从新活动中回退将在技术上将其放回启动器)

Answers:


281

处理片段this时,请始终使用而不是使用或引用上下文getActivity()。你应该打电话

getActivity().finish();

从片段中完成您的活动。


12
getActivity()null在某些情况下可能是这样。那我们该怎么办?
Matjaz Kristl 2012年

3
@ user983956在这种情况下,活动已被销毁,因此请不要致电finish
克里斯蒂安

2
提示:如果在放大视图之前尝试使用getActivity,则它可以为null
csanonymus 2014年

1
Activity应该是控制器/负责而不是片段,您应该通过回调接口对Activity进行回调,并让Activity决定是否应自行完成。
艾哈迈德(Ahmed)2015年

1
另外,如果您在活动中注入了单例,请不要忘记销毁它们,否则会造成内存泄漏,或者如果有回调将其删除,即。,如果(getActivity()!= null){getActivity()。removeCallbacks(); getActivity()。destroy(); }
omersem 2016年

26

实际上...

我不会让Fragment尝试完成活动。我认为,这对片段有太多的权威。相反,我将在此处使用该指南:http : //developer.android.com/training/basics/fragments/communicating.html

让Fragment定义Activity必须实现的接口。致电“活动”,然后让“活动”决定如何处理信息。如果活动希望自己完成,那就可以。


2
这是一个好主意,因为单个活动可以包含多个片段。如您所述,片段与活动进行通信的首选方式是通过接口。
Sasquatch 2014年

11

正如乔恩·汉考克Jon F Hancock)所提到的,这就是片段通过建议关闭活动来“关闭”活动的方式。这使得片段是可移植的,这就是它们的原因。如果在其他活动中使用它,则可能不想关闭该活动。

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

玩家活动

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

每次我使用finish关闭片段时,整个活动都会关闭。根据文档,片段应该保留下来,只要父活动仍然存在即可。

相反,我发现可以通过使用以下语句将视图更改回父活动:setContentView(R.layout.activity_main);

这使我返回到父活动。

我希望这可以帮助其他可能正在寻找这个的人。




1

在Fragment中使用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

2020年6月15日-更新的答案。

您有Java和Kotlin的两个选项。但是,两种方法的逻辑是相同的。您应该在调用finish()方法之后调用活动

回答科特林

如果您的活动不能为空,请使用Answer_1。但是,如果您的活动可以为null,请使用Answer_2

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

回答Java,

getActivity().finish();

@canerkaseler


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.