片段生命周期 - 在显示/隐藏时调用哪个方法?

问题描述 投票:84回答:10

我使用以下方法通过显示/隐藏它们来切换片段(在我的NavigationDrawer中)。

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

我不清楚的是当我显示或隐藏它时,会调用Fragments生命周期的哪个方法? (因为没有像onShow()或onHide()这样的方法,我不太清楚要使用什么)。我想在显示和隐藏某个片段时执行特定操作。

android android-fragments lifecycle fragmenttransaction
10个回答
109
投票

与活动生命周期类似,当片段变为可见时,Android会调用onStart()。当片段变得不可见时,通常会调用onStop(),但也可以在以后调用它。

根据您的布局,当您的片段尚未显示时,Android甚至可以调用onStart(),但它属于可见的父容器。例如,这对android.support.v4.view.ViewPager有效,它要求您覆盖Fragment.setUserVisibleHint()方法。在任何情况下,如果您需要注册/取消注册BroadcastReceivers或其他侦听器,您可以安全地使用onStart()onStop()方法,因为这些方法将始终被调用。

注意:某些片段容器可以保持不可见的片段启动。要处理这种情况,您可以覆盖Fragment.onHiddenChanged(boolean hidden)。根据documentation,片段必须同时启动和可见(不隐藏),以便用户可见。

更新:如果您使用android.support.v4.widget.DrawerLayout,那么即使抽屉打开,抽屉下方的片段也会保持开始并可见。在这种情况下,你需要使用DrawerLayout.setDrawerListener()并听取onDrawerClosed()onDrawerOpened()回调。


0
投票

当然你可以覆盖Use this methodsetUserVisibleHint但是如果你需要访问setMenuVisibilityContext,它们将在那里为空!还有另一种方法Activity,它总是有可用的上下文,但它只会在创建片段时调用一次,如果你开始在寻呼机中的片段之间移动,你会看到它不会在第二个视图中调用然后。

那么......现在该怎么办?

解决方法非常简单,第一次使用onStart,后来使用onStart。您的代码可能如下所示:

片段类:

setMenuVisibility

这样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(); } 将始终可用于Context方法。


53
投票

我@Override这个方法并解决了我的问题:

@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if (hidden) {
        //do when hidden
    } else {
       //do when show
    }
}

34
投票

当然你可以@Overriede以下方法来做到这一点:

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            // Do your Work
        } else {
            // Do your Work
        }
    }

3
投票

视图寻呼机行为中的片段与常规片段容器不同。

试试这段代码:

    boolean mIsVisibleToUser;

    /**
     * is visible to user
     */
    public void show() {
        //do when show
    }

    /**
     * is invisible to user
     */
    public void hide() {
        //do when gone
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!mIsVisibleToUser && getUserVisibleHint()) {
            mIsVisibleToUser = true;
            show();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mIsVisibleToUser && getUserVisibleHint()) {
            mIsVisibleToUser = false;
            hide();
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isResumed()) {
            if (mIsVisibleToUser != isVisibleToUser) {
                mIsVisibleToUser = isVisibleToUser;
                if (isVisibleToUser) show();
                else hide();
            }
        }
    }

    public boolean isVisibleToUser() {
        return mIsVisibleToUser;
    }

2
投票

试试这段代码:

@Override
public void setUserVisibleHint(boolean visible)
{
    super.setUserVisibleHint(visible);
    if (visible && isResumed())
    {
         onResume();
    }
}

@Override
public void onResume()
{
    super.onResume();
    if (!getUserVisibleHint())
    {
        return;
    }

    //Add your code this section
}

1
投票

只需在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;
    }
}

并在onCreateView()中创建此代码:

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  if(!isActive){
      init();
  }
}

1
投票

当片段可见并且您在活动中使用viewpager时,调用片段方法的另一种方法。

//首先你创建一个接口

public interface ShowFragmentVisible{
      public void showFragment();}

//之后,这个接口在Fragment中实现

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

//现在进入Activity,然后创建接口对象,并在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

1
投票

您可以使用'onCreateView'(或'onActivityCreated')和'onHiddenChanged'。使用'onCreateView'进行首次演出,并在以后使用'onHiddenChanged'。事务控制不会调用'setMenuVisibility'。

@Override
public View OnCreateView() {
   // fragment will show first
}

@Override
public void onHiddenChanged(boolean hidden) {
    if (!hidden) {
        // fragment will show 
    }
    else {
        // fragment will hide
    }
}

0
投票

setUserVisibleHintonCreateView之前打电话。并且您无法更新我使用的setUserVisibleHint中的任何View

public void setMenuVisibility(final boolean visible)

可见性和onHiddenChanged()没有第一次调用。它在隐藏状态改变时调用。因为一个fragment is visible by default。为了第一次实现这种方法,你必须调用mFragmentTransaction.hide(oldFragment)然后它将工作

注意

如果你想使用setUserVisiblehint并更新View qazxsw poi

© www.soinside.com 2019 - 2024. All rights reserved.