我在一个活动中有多个片段。在一个按钮点击我开始一个新的片段,添加到backstack。我自然希望调用当前Fragment的onPause()方法和新Fragment的onResume()方法。但这并没有发生。

LoginFragment.java

public class LoginFragment extends Fragment{
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      final View view  =   inflater.inflate(R.layout.login_fragment, container, false);
      final FragmentManager mFragmentmanager =  getFragmentManager();

      Button btnHome  = (Button)view.findViewById(R.id.home_btn);
      btnHome.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view){
           HomeFragment fragment    = new HomeFragment();
           FragmentTransaction ft2   =  mFragmentmanager.beginTransaction();
           ft2.setCustomAnimations(R.anim.slide_right, R.anim.slide_out_left
                    , R.anim.slide_left, R.anim.slide_out_right);
           ft2.replace(R.id.middle_fragment, fragment);
           ft2.addToBackStack(""); 
           ft2.commit();    
         }
      });
  }

  @Override
  public void onResume() {
     Log.e("DEBUG", "onResume of LoginFragment");
     super.onResume();
  }

  @Override
  public void onPause() {
    Log.e("DEBUG", "OnPause of loginFragment");
    super.onPause();
  }
}

HomeFragment.java

public class HomeFragment extends Fragment{
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     final View view  =   inflater.inflate(R.layout.login_fragment, container, false);
  }

  @Override
  public void onResume() {
     Log.e("DEBUG", "onResume of HomeFragment");
     super.onResume();
  }

  @Override
  public void onPause() {
     Log.e("DEBUG", "OnPause of HomeFragment");
     super.onPause();
  }
}

我所期待的是,

单击按钮时,LoginFragment将被替换为 的HomeFragment、LoginFragment的onPause()和onResume() HomeFragment被调用 当按下back键时,HomeFragment弹出,LoginFragment弹出 以及HomeFragment的onPause()和LoginFragment的onResume() 被调用。

我得到的是,

单击按钮时,HomeFragment被正确替换 LoginFragment, HomeFragment的onResume()被调用,但onPause()被调用 LoginFragment从来不被调用。 当向后按,HomeFragment是正确弹出显示 LoginFragment, HomeFragment的onPause()被调用,但onResume() 的LoginFragment从未被调用。

这是正常行为吗?为什么LoginFragment的onResume()没有被调用,当我按下返回按钮。


当前回答

你不能简单地将一个片段添加到一个片段中。这需要在FragmentActivity中发生。我假设你在一个FragmentActivity中创建LoginFragment,所以为了让这个工作,你需要在登录关闭时通过FragmentActivity添加HomeFragment。

一般来说,你需要一个FragmentActivity类,从那里你可以将每个Fragment添加到FragmentManager中。在Fragment类中不可能做到这一点。

其他回答

Since you have used ft2.replace(), FragmentTransaction.remove() method is called and the Loginfragment will be removed. Refer to this. So onStop() of LoginFragment will be called instead of onPause(). (As the new fragment completely replaces the old one). But since you have also used ft2.addtobackstack(), the state of the Loginfragment will be saved as a bundle and when you click back button from HomeFragment, onViewStateRestored() will be called followed by onStart() of LoginFragment. So eventually onResume() won't be called.

在创建片段事务时,请确保添加以下代码。

// Replace whatever is in the fragment_container view with this fragment, 
// and add the transaction to the back stack 
transaction.replace(R.id.fragment_container, newFragment); 
transaction.addToBackStack(null); 

还要确保在将事务添加到backstack后提交事务

片段必须始终嵌入到活动中,并且片段的生命周期直接受到宿主活动生命周期的影响。例如,当活动暂停时,其中的所有片段也暂停,当活动被销毁时,所有片段也暂停

我在我的活动中使用KOTLIN

supportFragmentManager.addOnBackStackChangedListener {
                val f = supportFragmentManager.findFragmentById(R.id.fragment_container)

                if (f?.tag == "MyFragment")
                {
                    //doSomething
                }
            }

你不能简单地将一个片段添加到一个片段中。这需要在FragmentActivity中发生。我假设你在一个FragmentActivity中创建LoginFragment,所以为了让这个工作,你需要在登录关闭时通过FragmentActivity添加HomeFragment。

一般来说,你需要一个FragmentActivity类,从那里你可以将每个Fragment添加到FragmentManager中。在Fragment类中不可能做到这一点。