フラグメントのライフサイクル-表示/非表示時に呼び出されるメソッドはどれですか?


99

以下のメソッドを使用して、フラグメントを表示/非表示にして(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()などのメソッドがないため、何を使用すればよいかわからない)。特定のフラグメントを表示および非表示にしたときに特定のアクションを実行したい。


Fragment.show()を呼び出すと、ある時点でフラグメントがトリガーonCreate()されonCreateDialog()、が続き、その後onCreateView()
Somesome Somewhere

回答:


122

アクティビティのライフサイクルと同様に、フラグメントが表示されると、AndroidはonStart()を呼び出します。onStop()通常、フラグメントが非表示になったときに呼び出されますが、後で呼び出すこともできます。

レイアウトによってonStart()は、フラグメントがまだ表示されていない場合でもAndroidが呼び出すことができますが、フラグメントは表示されている親コンテナーに属しています。たとえば、これはメソッドandroid.support.v4.view.ViewPagerをオーバーライドする必要がある場合に有効ですFragment.setUserVisibleHint()。いずれの場合でも、BroadcastReceiversまたはその他のリスナーを登録/登録解除する必要がある場合は、メソッドonStart()onStop()メソッドを安全に使用できます。これらは常に呼び出されるためです。

注:一部のフラグメントコンテナーは、非表示のフラグメントを開始したままにすることができます。この状況に対処するには、オーバーライドできますFragment.onHiddenChanged(boolean hidden)ドキュメントによると、ユーザーに表示するには、フラグメントが開始され、表示されている(非表示ではない)必要があります。

更新:使用するandroid.support.v4.widget.DrawerLayoutと、ドロワーが開いていても、ドロワーの下のフラグメントが開始され、表示されたままになります。この場合、コールバックを使用DrawerLayout.setDrawerListener()してリッスンする必要がonDrawerClosed()ありonDrawerOpened()ます。


14
onStopおよびonPauseフラグメントは、トランザクションを使用して見えなくなったときに呼び出されません。それにもかかわらず、onHiddenChangeds1riusの答えを示唆するように呼び出されます
Yoann Hercouet 14

これはNavigationDrawerでは機能しません。onHiddenChangedは、v4 / v11サポートライブラリでは呼び出されません。onStartとonResumeは、ドロワーレイアウトが開いたときに常に呼び出されるわけではありません。
drdrej

@drdrej問題は、ドロワーがフラグメントを完全に非表示にしないことです。サポートライブラリのDrawerLayoutを使用する場合は、DrawerListenerを使用する必要があります。
sergej shafarenka

69

このメソッドを@オーバーライドして、問題を解決します。

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

1
解決しないことを試みましたがsetUserVisibleHintstackoverflow.com
a / 18375436/1815624の

36

もちろん、次のメソッドを@Overrideすることもできます。

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

また、呼び出しによってフラグメントがユーザーに表示されるかどうかを簡単に知ることができますgetUserVisibleHint()
ARiF

2
setUserVisibleHintはビューページャーでは機能しますが、通常のフラグメントコンテナーでは機能しません。
MikeL 2017

このおかげで私の問題が解決します:)
RAJESH KUMAR ARUMUGAM

これは私にとってViewPagerで機能しました。onHiddenChangedが機能しませんでした。
live-love

私の問題を解決しました!
Jad Chahine

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
}

2

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

onHiddenChanged()がフラグメントで呼び出されない
matdev

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

isVisibleToUser && getView() != null私にとって完璧に働きました!
ボビー

1

フラグメントが表示されていて、アクティビティでビューページャーを使用しているときにフラグメントメソッドを呼び出す別の方法。

//まず最初にインターフェースを作成します

public interface ShowFragmentVisible{
      public void showFragment();}

//その後、このインターフェイスはそのようなFragment内部に実装します

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

//アクティビティに移動し、インターフェイスのオブジェクトを作成して、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

0

setUserVisibleHint前にお電話くださいonCreateView。私が使用するsetUserVisibleHint内のビューは更新できません

public void setMenuVisibility(final boolean visible)

以下のための可視性とonHiddenChanged()を初めて呼び出すことはありませんでした。非表示の状態が変化すると呼び出されます。なぜならfragment is visible by default。このメソッドを初めて実現するために呼び出す必要がありますがmFragmentTransaction.hide(oldFragment)、それは機能します

注意

setUserVisibleヒントを使用してビュー更新する場合このメソッドを使用


0

もちろん、setUserVisibleHintorをオーバーライドすることもできますsetMenuVisibilityが、Contextor にアクセスする必要がある場合Activityは、nullになります。onStart常に手元にあるコンテキストを使用できる別のメソッドがありますが、フラグメントの作成時に一度だけ呼び出され、ページャーでフラグメント間を移動し始めると、2番目以降のビューで呼び出されないことがわかります。 。

だから...今何をすべきか?

回避策は非常に簡単です。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は常にdoSth()メソッドで使用できます。


0

これだけがうまくいきました!! そして、setUserVisibleHint(...)現在は廃止されています(最後にドキュメントを添付しました)。これは、他の回答が廃止されることを意味します;-)

public class FragmentFirewall extends Fragment {
    /**
     * Required cause "setMenuVisibility(...)" is not guaranteed to be
     * called after "onResume()" and/or "onCreateView(...)" method.
     */
    protected void didVisibilityChange() {
        Activity activity = getActivity();
        if (isResumed() && isMenuVisible()) {
            // Once resumed and menu is visible, at last
            // our Fragment is really visible to user.
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        didVisibilityChange();
    }

    @Override
    public void setMenuVisibility(boolean visible) {
        super.setMenuVisibility(visible);
        didVisibilityChange();
    }
}

テスト済みで動作しNaviagationDrawerisMenuVisible()常に戻りますtrueonResume()十分だと思われますが、サポートViewPagerもしたいと考えています)。

setUserVisibleHint廃止予定です。このメソッドをオーバーライドする場合、渡すときに実装される動作trueをに移動しFragment.onResume()、渡すときに実装される動作falseをに移動する必要がありますFragment.onPause()

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.