首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >未在后台堆栈上调用片段onResume() & onPause()

未在后台堆栈上调用片段onResume() & onPause()
EN

Stack Overflow用户
提问于 2012-07-04 17:23:32
回答 20查看 278.9K关注 0票数 217

我在一个活动中有多个片段。单击一个按钮,我将开始一个新的片段,并将其添加到backstack。我自然希望调用当前片段的onPause()方法和新片段的onResume()。好吧,这是不会发生的。

LoginFragment.java

代码语言:javascript
复制
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

代码语言:javascript
复制
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();
  }
}

我所期待的是,

  1. 单击按钮时,LoginFragment将替换为HomeFragmentLoginFragment,的onPause()HomeFragmentonResume()将调用
  2. 当按下back时,弹出HomeFragment并显示LoginFragment,并调用HomeFragment的D22和LoginFragment的D25。

我得到的是,

  1. 单击按钮时,HomeFragment正确替换了HomeFragmentLoginFragment,onResume(),但从未调用过LoginFragment的onPause()。
  2. 按下后键时,HomeFragment的onPause()正确弹出,显示调用了HomeFragmentLoginFragment,onPause(),但从未调用过LoginFragment的onResume()。

这是正常的行为吗?为什么当我按下后退按钮时没有调用LoginFragmentonResume()

EN

回答 20

Stack Overflow用户

回答已采纳

发布于 2013-04-27 21:55:02

只有在调用活动onResume()onPause()时,才会调用片段onResume()onPause()。它们与Activity紧密耦合。

阅读Handling the Fragment Lifecycle section of this article

票数 199
EN

Stack Overflow用户

发布于 2013-04-27 21:45:08

  • 由于您已经使用了ft2.replace(),因此将调用FragmentTransaction.remove()方法并移除该Loginfragment。请参阅this。因此,将调用LoginFragmentonStop()而不是onPause()
  • ,但由于您还使用了ft2.addtobackstack(),因此Loginfragment的状态将保存为一个包,当您在HomeFragment中单击back按钮时,将调用onViewStateRestored(),然后调用onStart() of LoginFragment。所以最终onResume()将不会被调用。
票数 23
EN

Stack Overflow用户

发布于 2016-11-25 01:41:30

这是我对Gor答案的更健壮的版本(使用fragments.size()是不可靠的,因为在片段弹出后大小没有减少)

代码语言:javascript
复制
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if (getFragmentManager() != null) {

                Fragment topFrag = NavigationHelper.getCurrentTopFragment(getFragmentManager());

                if (topFrag != null) {
                    if (topFrag instanceof YourFragment) {
                        //This fragment is being shown. 
                    } else {
                        //Navigating away from this fragment. 
                    }
                }
            }
        }
    });

和'getCurrentTopFragment‘方法:

代码语言:javascript
复制
public static Fragment getCurrentTopFragment(FragmentManager fm) {
    int stackCount = fm.getBackStackEntryCount();

    if (stackCount > 0) {
        FragmentManager.BackStackEntry backEntry = fm.getBackStackEntryAt(stackCount-1);
        return  fm.findFragmentByTag(backEntry.getName());
    } else {
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null && fragments.size()>0) {
            for (Fragment f: fragments) {
                if (f != null && !f.isHidden()) {
                    return f;
                }
            }
        }
    }
    return null;
}
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11326155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档