804

問題:フラグメントが実際に表示される前に、フラグメントが起動onResume()されます。ViewPager

たとえば、とが付いた2つのフラグメントがViewPagerありFragmentPagerAdapterます。2番目のフラグメントは、許可されたユーザーのみが使用できます。フラグメントが表示されたら(アラートダイアログを使用して)ログインするようにユーザーに依頼する必要があります。

ただし、ViewPager2番目のフラグメントをキャッシュするために、最初のフラグメントが表示されているときに2番目のフラグメントが作成され、ユーザーがスワイプを開始したときに表示されます。

したがって、onResume()イベントは、表示されるずっと前に2番目のフラグメントで発生します。そのため、適切なタイミングでダイアログを表示するために2番目のフラグメントが表示されたときに発生するイベントを見つけようとしています。

これはどのように行うことができますか?

4

26 に答える 26

604

フラグメントがViewPagerに表示されるタイミングを決定する方法

あなたはあなたのでオーバーライドすることによって以下を行うことができsetUserVisibleHintますFragment

public class MyFragment extends Fragment {
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
        }
        else {
        }
    }
}
于 2012-06-17T23:42:09.847 に答える
531

更新:Androidサポートライブラリ(rev 11)は、ユーザーに表示されるヒントの問題を最終的に修正しました。フラグメントにサポートライブラリを使用する場合、gornの回答で説明されているように、変更をキャプチャするために安全に使用getUserVisibleHint()またはオーバーライドできます。setUserVisibleHint()

UPDATE1これは。に関する1つの小さな問題getUserVisibleHint()です。この値はデフォルトですtrue

// Hint provided by the app that this fragment is currently visible to the user.
boolean mUserVisibleHint = true;

setUserVisibleHint()そのため、呼び出される前に使用しようとすると問題が発生する可能性があります。回避策として、このような方法で値を設定することができますonCreate

public void onCreate(@Nullable Bundle savedInstanceState) {
    setUserVisibleHint(false);

時代遅れの答え:

ほとんどのユースケースでは、一度に1ページしか表示されませんが、で使用してViewPagerいる場合は、事前にキャッシュされたフラグメントも「表示」状態(実際には非表示)になります。FragmentStatePagerAdapterAndroid Support Library pre-r11

オーバーライドします:

public class MyFragment extends Fragment {
    @Override
    public void setMenuVisibility(final boolean visible) {
        super.setMenuVisibility(visible);
        if (visible) {
            // ...
        }
    }
   // ...
}

ViewPagerの1つのフラグメントだけが実際にそのメニュー項目を親アクティビティの項目と一緒に配置できるため、フラグメントのフォーカス状態をキャプチャすることは、「可視性」の最も適切な状態であると私は思います。

于 2012-09-21T02:56:33.283 に答える
147

onResume()これにより、期待する通常の動作が復元されるようです。ホームキーを押してアプリを終了してからアプリに再度入るとうまく機能します。 onResume()連続して2回呼び出されることはありません。

@Override
public void setUserVisibleHint(boolean visible)
{
    super.setUserVisibleHint(visible);
    if (visible && isResumed())
    {
        //Only manually call onResume if fragment is already visible
        //Otherwise allow natural fragment lifecycle to call onResume
        onResume();
    }
}

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

    //INSERT CUSTOM CODE HERE
}
于 2014-08-03T03:02:12.820 に答える
74

これを使用する別の方法がありonPageChangeListenerます:

  ViewPager pager = (ViewPager) findByViewId(R.id.viewpager);
  FragmentPagerAdapter adapter = new FragmentPageAdapter(getFragmentManager);
  pager.setAdapter(adapter);
  pager.setOnPageChangeListener(new OnPageChangeListener() {

  public void onPageSelected(int pageNumber) {
    // Just define a callback method in your fragment and call it like this! 
    adapter.getItem(pageNumber).imVisible();

  }

  public void onPageScrolled(int arg0, float arg1, int arg2) {
    // TODO Auto-generated method stub

  }

  public void onPageScrollStateChanged(int arg0) {
    // TODO Auto-generated method stub

  }
});
于 2012-08-03T14:41:51.913 に答える
58

setUserVisibleHint()時々前に 、そして時々後に呼び出されonCreateView()、それが問題を引き起こします。

これを克服するには、メソッドisResumed()内もチェックする必要がありますsetUserVisibleHint()。しかし、この場合、フラグメントが再開されて表示された場合にのみsetUserVisibleHint()呼び出され、作成されたときではないことに気付きました。

したがって、フラグメントがvisibleであるときに何かを更新する場合は、更新関数をとの両方に配置しonCreate()ますsetUserVisibleHint()

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

更新:それでも私myUIUpdate()は時々2回呼び出されることに気づきました。理由は、3つのタブがあり、このコードが2番目のタブにある場合、最初に1番目のタブを開くと、表示されていない場合でも2番目のタブも作成されてmyUIUpdate()呼び出されるためです。次に、2番目のタブにスワイプすると、myUIUpdate()fromif (visible && isResumed())が呼び出され、その結果、myUIUpdate()1秒間に2回呼び出される場合があります。

もう1つの問題!visiblesetUserVisibleHint1)フラグメント画面を終了するときと、2)作成される前に、最初にフラグメント画面に切り替えるときの両方で呼び出されることです。

解決:

private boolean fragmentResume=false;
private boolean fragmentVisible=false;
private boolean fragmentOnCreated=false;
...

@Override
public View onCreateView(...){
    ...
    //Initialize variables
    if (!fragmentResume && fragmentVisible){   //only when first time fragment is created
        myUIUpdate();
    }
    ...        
}

@Override
public void setUserVisibleHint(boolean visible){
    super.setUserVisibleHint(visible);
    if (visible && isResumed()){   // only at fragment screen is resumed
        fragmentResume=true;
        fragmentVisible=false;
        fragmentOnCreated=true;
        myUIUpdate();
    }else  if (visible){        // only at fragment onCreated
        fragmentResume=false;
        fragmentVisible=true;
        fragmentOnCreated=true;
    }
    else if(!visible && fragmentOnCreated){// only when you go out of fragment screen
        fragmentVisible=false;
        fragmentResume=false;
    }
}

説明:

fragmentResumefragmentVisible:フラグメントが作成されて表示されたときにのみ呼び出され、再開時に呼び出されないようにしますmyUIUpdate()onCreateView()また、1番目のタブにいるときの問題も解決します。2番目のタブは表示されていなくても作成されます。これはそれを解決し、フラグメント画面が表示されているかどうかを確認しますonCreate

fragmentOnCreated:フラグメントが表示されないようにし、フラグメントを最初に作成するときに呼び出されないようにします。したがって、このif句は、フラグメントからスワイプしたときにのみ呼び出されます。

更新BaseFragmentこのすべてのコードをこのような コードに入れて、メソッドをオーバーライドできます。

于 2015-04-14T07:27:17.327 に答える
49

ViewPager2バージョン内およびViewPagerバージョンから、コールバックをandroidx.fragment:fragment:1.1.0使用onPauseonResumeて、ユーザーに現在表示されているフラグメントを判別できます。onResumeフラグメントが表示されたとき、および表示されなくなったときにコールバックが呼び出されonPauseます。

ViewPager2の場合、これはデフォルトの動作ですが、同じ動作を古いグッドに対してViewPager簡単に有効にすることができます。

最初のViewPagerでこの動作を有効にするには、コンストラクターFragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENTの2番目の引数としてパラメーターを渡す必要がありますFragmentPagerAdapter

FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

注: 1つのパラメーターを持つsetUserVisibleHint()メソッドとFragmentPagerAdapterコンストラクターは、Androidjetpackの新しいバージョンのFragmentで非推奨になりました。

于 2019-09-11T11:44:55.020 に答える
34

新しい

ViewPager2+ FragmentStateAdapter+ onResume()(フラグメント内)問題を解決します

古い回答(非推奨)

Fragment目に見える形で検出するには、使用するだけでは十分ではないとViewPager確信しています。 フラグメントが表示されているかどうかを確認するための私の解決策は次のとおりです。最初にviewpagerを起動するときに、ページを切り替えて、別のアクティビティ/フラグメント/背景/フォアグラウンドに移動します` setUserVisibleHint

public class BaseFragmentHelpLoadDataWhenVisible extends Fragment {
    protected boolean mIsVisibleToUser; // you can see this variable may absolutely <=> getUserVisibleHint() but it not. Currently, after many test I find that

    /**
     * This method will be called when viewpager creates fragment and when we go to this fragment background or another activity or fragment
     * NOT called when we switch between each page in ViewPager
     */
    @Override
    public void onStart() {
        super.onStart();
        if (mIsVisibleToUser) {
            onVisible();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mIsVisibleToUser) {
            onInVisible();
        }
    }

    /**
     * This method will called at first time viewpager created and when we switch between each page
     * NOT called when we go to background or another activity (fragment) when we go back
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        mIsVisibleToUser = isVisibleToUser;
        if (isResumed()) { // fragment have created
            if (mIsVisibleToUser) {
                onVisible();
            } else {
                onInVisible();
            }
        }
    }

    public void onVisible() {
        Toast.makeText(getActivity(), TAG + "visible", Toast.LENGTH_SHORT).show();
    }

    public void onInVisible() {
        Toast.makeText(getActivity(), TAG + "invisible", Toast.LENGTH_SHORT).show();
    }
}

説明以下のlogcat を注意深く確認すると、このソリューションが機能する理由がわかると思います。

最初の打ち上げ

Fragment1: setUserVisibleHint: isVisibleToUser=false isResumed=false
Fragment2: setUserVisibleHint: isVisibleToUser=false isResumed=false
Fragment3: setUserVisibleHint: isVisibleToUser=false isResumed=false
Fragment1: setUserVisibleHint: isVisibleToUser=true isResumed=false // AT THIS TIME isVisibleToUser=true but fragment still not created. If you do something with View here, you will receive exception
Fragment1: onCreateView
Fragment1: onStart mIsVisibleToUser=true
Fragment2: onCreateView
Fragment3: onCreateView
Fragment2: onStart mIsVisibleToUser=false
Fragment3: onStart mIsVisibleToUser=false

2ページに移動

Fragment1: setUserVisibleHint: isVisibleToUser=false isResumed=true
Fragment2: setUserVisibleHint: isVisibleToUser=true isResumed=true

3ページに移動

Fragment2: setUserVisibleHint: isVisibleToUser=false isResumed=true
Fragment3: setUserVisibleHint: isVisibleToUser=true isResumed=true

背景に移動:

Fragment1: onStop mIsVisibleToUser=false
Fragment2: onStop mIsVisibleToUser=false
Fragment3: onStop mIsVisibleToUser=true

フォアグラウンドに移動

Fragment1: onStart mIsVisibleToUser=false
Fragment2: onStart mIsVisibleToUser=false
Fragment3: onStart mIsVisibleToUser=true

デモプロジェクトはこちら

お役に立てば幸いです

于 2017-02-03T08:34:14.953 に答える
26
package com.example.com.ui.fragment;


import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.com.R;

public class SubscribeFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_subscribe, container, false);
        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if (isVisibleToUser) {
            // called here
        }
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }
}
于 2016-01-06T13:54:44.007 に答える
18

サブクラスでオーバーライドsetPrimaryItem()します。FragmentPagerAdapter私はこの方法を使用します、そしてそれはうまくいきます。

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    // This is what calls setMenuVisibility() on the fragments
    super.setPrimaryItem(container, position, object);

    if (object instanceof MyWhizBangFragment) {
        MyWhizBangFragment fragment = (MyWhizBangFragment) object;
        fragment.doTheThingYouNeedToDoOnBecomingVisible();
    }
}
于 2015-06-19T18:34:21.477 に答える
14

そのためにオーバーライドFragment.onHiddenChanged()します。

public void onHiddenChanged(boolean hidden)

isHidden()フラグメントの非表示状態(によって返される)が変更されたときに呼び出されます。フラグメントは隠されていない状態から始まります。これは、フラグメントがそれから状態を変更するたびに呼び出されます。

パラメータ
hidden- boolean:フラグメントが非表示になっている場合はtrue、表示されていない場合はfalse。

于 2012-09-09T12:04:16.910 に答える
8

これだけでうまくいきました!! 現在は非推奨に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();
    }
}

テストNaviagationDrawerされ、同様に動作し、isMenuVisible()常に戻ってきますtrue(そしてonResume()十分に思えますが、私たちもサポートしたいと思いViewPagerます)。

setUserVisibleHint非推奨です。このメソッドをオーバーライドする場合は、パスイン時に実装された動作trueをに移動しFragment.onResume()、パスイン時に実装された動作をfalseに移動する必要がありますFragment.onPause()

于 2020-07-28T06:13:43.057 に答える
5

私はそれを理解しonCreateOptionsMenuonPrepareOptionsMenuフラグメントが実際に見える場合にのみ呼び出されるメソッドを理解しました。このように動作するメソッドが見つかりませんでした。また、試しOnPageChangeListenerましたが、メソッドで初期化された変数が必要な場合など、状況によっては機能しませんでしたonCreate

したがって、これらの2つの方法は、特に小さなジョブと短いジョブの回避策として、この問題に使用できます。

これはより良い解決策だと思いますが、最善ではありません。私はこれを使用しますが、同時により良い解決策を待ちます。

よろしく。

于 2014-06-24T08:20:46.777 に答える
5

setUserVisibleHint(boolean visible)非推奨になりました。これが正しい解決策です

FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)

バージョンのViewPager2およびViewPagerでは、をandroidx.fragment:fragment:1.1.0使用onPause()onResume()て、現在ユーザーに表示されているフラグメントを判別できます。onResume()フラグメントが表示されたとき、およびフラグメントが表示されなくなったときに呼び出されonPauseます。

最初のViewPagerでこの動作を有効にするにFragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENTは、コンストラクターの2番目の引数としてパラメーターを渡す必要がありますFragmentPagerAdapter

于 2020-06-06T10:06:01.020 に答える
2

kris larsonによってpageradapterのsetPrimaryItemをオーバーライドする、ここに投稿された別のソリューションは、ほとんど私のために機能しました。ただし、このメソッドは、セットアップごとに複数回呼び出されます。また、このメソッドが呼び出された最初の数回は準備ができていないため、フラグメント内のビューなどからNPEを取得しました。次の変更で、これは私のために働きました:

private int mCurrentPosition = -1;

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    super.setPrimaryItem(container, position, object);

    if (position == mCurrentPosition) {
        return;
    }

    if (object instanceof MyWhizBangFragment) {
        MyWhizBangFragment fragment = (MyWhizBangFragment) object;

        if (fragment.isResumed()) {
            mCurrentPosition = position;
            fragment.doTheThingYouNeedToDoOnBecomingVisible();
        }
    }
}
于 2016-04-06T12:57:46.497 に答える
2

FragmentStatePagerAdapters3つのタブで作業しているときに同じ問題が発生しました。最初のタブがクリックされるたびにDilaogを表示し、他のタブをクリックすると非表示にする必要がありました。

単独でオーバーライドsetUserVisibleHint()しても、現在表示されているフラグメントを見つけるのに役立ちませんでした。

3番目のタブからクリックした場合----->1番目のタブ。2番目のフラグメントと1番目のフラグメントで2回トリガーされました。isResumed()メソッドと組み合わせました。

    @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    isVisible = isVisibleToUser;

    // Make sure that fragment is currently visible
    if (!isVisible && isResumed()) {
        // Call code when Fragment not visible
    } else if (isVisible && isResumed()) {
       // Call code when Fragment becomes visible.
    }

}
于 2016-11-11T19:37:46.453 に答える
2

フラグメント内に次のコードを追加します

@Override
public void setMenuVisibility(final boolean visible) 
 {
    super.setMenuVisibility(visible);
    if (visible && isResumed()) 
     {

     }
}
于 2017-01-02T18:24:31.593 に答える
2

MVPの特殊なケースでは、フラグメントがプレゼンターにビューが表示されたことを通知する必要があり、プレゼンターはDaggerによってに注入されfragment.onAttach()ます。

setUserVisibleHint()十分ではありません。対処する必要のある3つの異なるケースを検出しました(onAttach()プレゼンターがいつ利用可能かを知るために言及されています)。

  1. フラグメントが作成されました。システムは次の呼び出しを行います。

    setUserVisibleHint() // before fragment's lifecycle calls, so presenter is null
    onAttach()
    ...
    onResume()
    
  2. フラグメントはすでに作成されており、ホームボタンが押されています。アプリをフォアグラウンドに復元する場合、これは次のように呼び出されます。

    onResume()
    
  3. 向きの変更:

    onAttach() // presenter available
    onResume()
    setUserVisibleHint()
    

可視性のヒントがプレゼンターに一度だけ届くようにしたいので、次のようにします。

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.fragment_list, container, false);
    setHasOptionsMenu(true);

    if (savedInstanceState != null) {
        lastOrientation = savedInstanceState.getInt(STATE_LAST_ORIENTATION,
              getResources().getConfiguration().orientation);
    } else {
        lastOrientation = getResources().getConfiguration().orientation;
    }

    return root;
}

@Override
public void onResume() {
    super.onResume();
    presenter.onResume();

    int orientation = getResources().getConfiguration().orientation;
    if (orientation == lastOrientation) {
        if (getUserVisibleHint()) {
            presenter.onViewBecomesVisible();
        }
    }
    lastOrientation = orientation;
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (presenter != null && isResumed() && isVisibleToUser) {
        presenter.onViewBecomesVisible();
    }
}

@Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(STATE_LAST_ORIENTATION, lastOrientation);
}
于 2017-05-08T15:30:26.363 に答える
2

による検出focused view

これは私のために働く

public static boolean isFragmentVisible(Fragment fragment) {
    Activity activity = fragment.getActivity();
    View focusedView = fragment.getView().findFocus();
    return activity != null
            && focusedView != null
            && focusedView == activity.getWindow().getDecorView().findFocus();
}
于 2017-12-16T11:43:00.323 に答える
1

私も同じ問題を抱えていました。ViewPager他のフラグメントライフサイクルイベントを実行し、その動作を変更できませんでした。フラグメントと利用可能なアニメーションを使用して、簡単なポケットベルを作成しました。 SimplePager

于 2014-03-11T18:35:48.193 に答える
1

私はこれを使用しました、そしてそれは働きました!

mContext.getWindow().getDecorView().isShown() //boolean
于 2018-09-21T10:57:28.917 に答える
1

私は子フラグメントでSectionsPagerAdapterをサポートしているので、多くの頭痛の種の後、私はついにこのトピックのソリューションに基づいた実用的なバージョンを手に入れました:

public abstract class BaseFragment extends Fragment {

    private boolean visible;
    private boolean visibilityHintChanged;

    /**
     * Called when the visibility of the fragment changed
     */
    protected void onVisibilityChanged(View view, boolean visible) {

    }

    private void triggerVisibilityChangedIfNeeded(boolean visible) {
        if (this.visible == visible || getActivity() == null || getView() == null) {
            return;
        }
        this.visible = visible;
        onVisibilityChanged(getView(), visible);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (!visibilityHintChanged) {
            setUserVisibleHint(false);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (getUserVisibleHint() && !isHidden()) {
            triggerVisibilityChangedIfNeeded(true);
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        triggerVisibilityChangedIfNeeded(!hidden);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        visibilityHintChanged = true;
        if (isVisibleToUser && isResumed() && !isHidden()) {
            triggerVisibilityChangedIfNeeded(true);
        } else if (!isVisibleToUser) {
            triggerVisibilityChangedIfNeeded(false);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        triggerVisibilityChangedIfNeeded(false);
    }

    @Override
    public void onStop() {
        super.onStop();
        triggerVisibilityChangedIfNeeded(false);
    }

    protected boolean isReallyVisible() {
        return visible;
    }
}
于 2019-05-09T09:56:27.537 に答える
0

ビューページャーのフラグメントがユーザーに表示されているときにタイマーを起動しようとしたときに、この問題が発生しました。

タイマーは常に、フラグメントがユーザーに表示される直前に開始されました。これはonResume()、フラグメントを表示する前に、フラグメント内のメソッドが呼び出されるためです。

私の解決策は、onResume()メソッドをチェックインすることでした。フラグメント8がビューページャーの現在のフラグメントであるときに、特定のメソッド'foo()'を呼び出したいと思いました。

@Override
public void onResume() {
    super.onResume();
    if(viewPager.getCurrentItem() == 8){
        foo();
        //Your code here. Executed when fragment is seen by user.
    }
}

お役に立てれば。私はこの問題がたくさん現れるのを見てきました。これは私が見た中で最も簡単な解決策のようです。他の多くは、より低いAPIなどと互換性がありません。

于 2015-08-05T14:12:26.417 に答える
0

setUserVisibleHint(false)アクティビティ/フラグメント停止では呼び出されないことに注意してください。register/unregisterリスナーなどを適切に確認するには、開始/停止を確認する必要があります。

また、setUserVisibleHint(false)フラグメントが非表示の状態で開始するかどうかもわかります。unregisterその場合、これまでに登録したことがないので、そこに行きたくありません。

@Override
public void onStart() {
    super.onStart();

    if (getUserVisibleHint()) {
        // register
    }
}

@Override
public void onStop() {
    if (getUserVisibleHint()) {
        // unregister
    }

    super.onStop();
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isVisibleToUser && isResumed()) {
        // register

        if (!mHasBeenVisible) {
            mHasBeenVisible = true;
        }
    } else if (mHasBeenVisible){
        // unregister
    }
}
于 2015-12-09T19:53:47.207 に答える
0

これを実装する簡単な方法は、フラグメントに移動する前にユーザーがログインしているかどうかを確認することです。

MainActivityでは、 onNavigationItemSelectedメソッド内でこのようなことを行うことができます。

 case R.id.nav_profile_side:


                if (User_is_logged_in) {

                    fragmentManager.beginTransaction()
                            .replace(R.id.content_frame
                                    , new FragmentProfile())
                            .commit();
                }else {

                    ShowLoginOrRegisterDialog(fragmentManager);

                }

                break;

ただし、ナビゲーションドロワーを使用している場合は、ProfileFragmentに移動していませんが、ドロワーでの選択がProfileに変更されます。

選択を現在の選択にリセットするには、以下のコードを実行します

        navigationView.getMenu().getItem(0).setChecked(true);
于 2019-05-28T17:35:03.357 に答える
0

非常に遅いかもしれません。これは私のために働いています。@Gobarおよび@krisSolutionsのコードを少し更新しました。のコードを更新する必要がありますPagerAdapter

setPrimaryItemタブが表示されるたびに呼び出され、その位置を返します。位置が同じである場合、私たちは動かないことを意味します。位置が変更され、現在の位置がクリックされたタブが-1に設定されていない場合。

private int mCurrentPosition = -1;

@Override
public void setPrimaryItem(@NotNull ViewGroup container, int position, @NotNull Object object) {
    // This is what calls setMenuVisibility() on the fragments
    super.setPrimaryItem(container, position, object);
    if (position == mCurrentPosition) {
        return;
    }
    if (object instanceof YourFragment) {
        YourFragment fragment = (YourFragment) object;
        if (fragment.isResumed()) {
            mCurrentPosition = position;
            fragment.doYourWork();//Update your function
        }
    } else {
        mCurrentPosition = -1;
    }
}
于 2020-09-24T06:46:26.653 に答える
-4

関連するFragmentStatePagerAdapterのCountメソッドをオーバーライドし、合計カウントから非表示にするページ数を引いたものを返すようにします。

 public class MyAdapter : Android.Support.V13.App.FragmentStatePagerAdapter
 {   
     private List<Fragment> _fragments;

     public int TrimmedPages { get; set; }

     public MyAdapter(Android.App.FragmentManager fm) : base(fm) { }

     public MyAdapter(Android.App.FragmentManager fm, List<Android.App.Fragment> fragments) : base(fm)
     {
         _fragments = fragments;

         TrimmedPages = 0;
     }

     public override int Count
     {
         //get { return _fragments.Count; }
         get { return _fragments.Count - TrimmedPages; }
     }
 }

したがって、ViewPagerに最初に追加されたフラグメントが3つあり、何らかの条件が満たされるまで最初の2つだけを表示する必要がある場合は、TrimmedPagesを1に設定してページ数をオーバーライドすると、最初の2つのページのみが表示されます。

これは最後のページには適していますが、最初または途中のページにはあまり役立ちません(これを行う方法はたくさんありますが)。

于 2013-01-11T21:28:09.303 に答える