Fragment lifecycle - which method is called upon s

2019-01-16 11:46发布

I am using the following method to switch between Fragments (in my NavigationDrawer) by showing / hiding them.

protected void showFragment(int container, Fragment fragment, String tag, String lastTag, boolean addToBackStack ) {

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();

        if ( lastTag != null && !lastTag.equals("")) {
            Fragment lastFragment = fragmentManager.findFragmentByTag( lastTag );
            if ( lastFragment != null ) {
                transaction.hide( lastFragment );
            }
        }

        if ( fragment.isAdded() ) {
            transaction.show( fragment );
        }
        else {
            transaction.add( container, fragment, tag );
        }

        if ( addToBackStack ) {
            transaction.addToBackStack( tag );
        }

        transaction.commit();

        // set the active tag
        activeFragTag = tag;
    }

What I am unclear about is which method of the Fragments lifecycle is called when I show or hide it? (since there is no method such as onShow() or onHide() im not quite sure what to use). I want to perform specific actions upon showing and hiding a certain Fragment.

8条回答
贪生不怕死
2楼-- · 2019-01-16 12:28

Just try this in your setUserVisibleHint()

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser && getView() != null){
        isActive = true;
        init();
    }else if(isVisibleToUser && getView() == null){
        isActive = false;
    }else{
        isActive = true;
    }
}

And create this code in onCreateView() :

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  if(!isActive){
      init();
  }
}
查看更多
我命由我不由天
3楼-- · 2019-01-16 12:32

Of course you could override setUserVisibleHint or setMenuVisibility but if you need to access Context or Activity, they will be null in there! There is another method onStart which always has the context available at hand, but it will only get called once upon creation of fragment and if you start moving between your fragments in a pager you will see that it won't get called in second view and afterwards.

So... what to do now?

The workaround is quite easy, use onStart for the first visit and setMenuVisibility for later ones. Your code will probably look like below :

Fragment class:

public class MyFragmentClass{
    private boolean isCurrentVisible = false;
...

@Override
public void onStart() {
    super.onStart();
    if (isCurrentVisible)
        doSth();
}

@Override
public void setMenuVisibility(boolean menuVisible){
    super.setMenuVisibility(menuVisible);
    this.isCurrentVisible = menuVisible;
    if(menuVisible && getContext() != null)
        doSth();
}

This way Context will always be available to doSth() method.

查看更多
乱世女痞
4楼-- · 2019-01-16 12:43

setUserVisibleHint call before onCreateView. and you can't update any View inside setUserVisibleHint I use

public void setMenuVisibility(final boolean visible)

for visibility and onHiddenChanged() didn't call for the first time. it calls when the hidden state changes. because a fragment is visible by default. In order to achieve this method for the first time you have to call mFragmentTransaction.hide(oldFragment) then it will work

Note

if you want to use setUserVisible hint and update View Use this method

查看更多
啃猪蹄的小仙女
5楼-- · 2019-01-16 12:44

Another way to calling fragment method when fragment is visible and you use viewpager in activity.

//first of all you create a interface

public interface ShowFragmentVisible{
      public void showFragment();}

//After that this interface implement inside Fragment like that

      public class MyFragment extends Fragment implements 
         ShowFragmentVisible {
            @Override
public void showFragment() {
}

// Now goes your Activity then create object of interface and call inside when addOnViewpagerListener

   ShowFragmentVisible showFragmentVisible;

@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);

    if (fragment instanceof ShowFragmentVisible) {
        showFragmentVisible = (ShowFragmentVisible) fragment;
    }

}
     //your viewpager method
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            if (position==0){
                showFragmentVisible.showFragment();

           }

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });


this is another alternative,but its work for me successfully
查看更多
迷人小祖宗
6楼-- · 2019-01-16 12:46

I @Override this method and resolve my problem:

@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if (hidden) {
        //do when hidden
    } else {
       //do when show
    }
}
查看更多
我只想做你的唯一
7楼-- · 2019-01-16 12:46

off-course you can @Overriede following method to do so:

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            // Do your Work
        } else {
            // Do your Work
        }
    }
查看更多
登录 后发表回答