ViewPagerからフラグメントを取得する


248

私はViewPager一緒にa FragmentStatePagerAdapterを使用して、3つの異なるフラグメントをホストしています:

  • [フラグメント1]
  • [フラグメント2]
  • [フラグメント3]

私が取得したいときFragment1からViewPagerFragmentActivity

何が問題で、どうすれば修正できますか?

回答:


504

主な答えは、フレームワークによって生成される名前に依存しています。それが変わると、それは機能しなくなります。

何このソリューションについて、オーバーライドinstantiateItem()destroyItem()あなたのFragment(State)PagerAdapter

public class MyPagerAdapter extends FragmentStatePagerAdapter {
    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

    public MyPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return ...;
    }

    @Override
    public Fragment getItem(int position) {
        return MyFragment.newInstance(...); 
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }
}

これは、利用可能なフラグメントを処理するときに私にはうまくいくようです。まだインスタンス化されていないフラグメントは、を呼び出すとnullを返しますgetRegisteredFragment。しかし、私は、現在取得し、主にこれを使用してきたFragmentのアウトViewPageradapater.getRegisteredFragment(viewPager.getCurrentItem())これは戻りませんnull

このソリューションの他の欠点は知りません。あれば教えてください。


41
これも私が考えることができる最良の解決策です。唯一の提案は多分ラップするだろうFragmentWeakReferenceあなたがごみ収集されてから破壊されたフラグメントを防ぐことはできません保証しますか?ちょうど正しいことのように思われます...
Alex Lockwood 2013年

7
MyPagerAdapterライフサイクル(つまり、回転)によって破壊された場合、何がregisterdFragments失われますか?ウィルActivity/ Fragment使用してMyPagerAdapter、それを保存する必要がありonSaveInstanceState、その後、新しいとそれを更新する必要がFragmentManagerREF?
Steven Byle

10
私が間違っていない場合(これを確認する必要があります)、getItemメソッドは(ご存じのとおり)呼び出されませんが、ローテーション後にフレームワークによって復元されるすべてのFragmentに対して、instantiateItemメソッドが呼び出されます。
Streets Of Boston

6
はい、ページャーに保持されている状態を復元するgetItemので、(すでに作成されているすべてのフラグについて)回転時に再度呼び出されないことを確認しました。場合は、それぞれのときに呼び出され、復元され、その後、このソリューションは、実際にはより安全で、将来の証明鉱山や受け入れ答えより。これを自分で試すことを検討します。FragmentManagerFragmentsinstantiateItemFragment
Steven Byle

6
@Dori壊れない。私の解決策は、「getItem()」呼び出しの結果を使用していません。代わりに、 'instantiateItem()'呼び出しから格納された結果を使用しています。また、格納されたフラグメントは 'destroyItem()'呼び出しでスパース配列から削除されるため、フラグメントのライフサイクルは壊れません。
Streets Of Boston

85

ViewPagerからフラグメントを取得するために、ここおよび他の関連するSOスレッド/ブログに多くの答えがあります。私が見たすべての人は壊れており、彼らは一般的に以下にリストされている2つのタイプのいずれかに分類されるようです。現在のフラグメントのみを取得したい場合は、他のいくつかの有効な解決策があります。このスレッドのこの他の回答のように。

使用FragmentPagerAdapterする場合は、以下を参照してください。使用している場合はFragmentStatePagerAdapterその価値を見て、これを。FragmentStateAdapterの現在のインデックスではないインデックスを取得することは、その性質上、完全に分解されてビューの外/ offScreenLimitの境界外になるほど有用ではありません。

不幸な道

誤り:FragmentPagerAdapter.getItem()が呼び出されたときに追加される、フラグメントの独自の内部リストを維持する

  • 通常、SparseArrayまたはMap
  • 私が見た多くの例の1つではなく、ライフサイクルイベントを説明しているため、このソリューションは脆弱です。でgetItem最初にページがスクロールされたとき(またはViewPager.setOffscreenPageLimit(x)> 0の場合に取得されたとき)にのみ呼び出されるためViewPager、ホスティングActivity/ Fragmentが強制終了または再起動SpaseArrayされた場合、カスタムFragmentPagerActivityが再作成されるときに内部が消去されますが、シーンの背後ではViewPagers内部フラグメントが再作成され、かつgetItemますNOTインデックスのいずれかのために呼び出されるので、インデックスからの断片を取得する能力が永遠に失われてしまいます。あなたはアウト節約を介してこれらのフラグメントの参照を復元することによってこれを説明することができますFragmentManager.getFragment()し、 putFragmentこれは厄介な私見を取得するために開始します。

誤り:内部で使用されているものと一致する独自のタグIDを作成しFragmentPagerAdapter、これを使用してページフラグメントをFragmentManager

  • これは、最初に内部アレイ液に負け-フラグメント参照の問題に対処するよう、より良いinsomuchですが、当然の答え上記および他の場所で、ネット上で指摘したように-それは、そのようハック感じている民間の内部メソッドViewPagerことができいつでも、またはどのOSバージョンでも変更できます。

このソリューションのために再作成されたメソッドは

private static String makeFragmentName(int viewId, long id) {
    return "android:switcher:" + viewId + ":" + id;
}

幸せな道: ViewPager.instantiateItem()

getItem()上記と同様のアプローチですが、ライフサイクルを壊さない方法は、インデックスが作成またはアクセスされるたびに前者が呼び出されるのではinstantiateItem()なく、フックすることですgetItem()この回答を見る

ハッピーパス:自分で構築する FragmentViewPager

最新のサポートライブラリのソースFragmentViewPagerから独自のクラスを構築し、フラグメントタグを生成するために内部で使用されるメソッドを変更します。下記のものと交換できます。これには、タグの作成が変更されず、常に危険なプライベートAPI /メソッドに依存しないことがわかっているという利点があります。

/**
 * @param containerViewId the ViewPager this adapter is being supplied to
 * @param id pass in getItemId(position) as this is whats used internally in this class
 * @return the tag used for this pages fragment
 */
public static String makeFragmentName(int containerViewId, long id) {
    return "android:switcher:" + containerViewId + ":" + id;
}

次に、ドキュメントに記載されているように、インデックスに使用されるフラグメントを取得する場合は、このメソッド(カスタムFragmentPagerAdapterまたはサブクラスに配置できます)などを呼び出すだけで、getItemがまだ呼び出されていない場合は結果がnullになる可能性があることに注意してください。つまり、そのページはまだ作成されていません。

/**
 * @return may return null if the fragment has not been instantiated yet for that position - this depends on if the fragment has been viewed
 * yet OR is a sibling covered by {@link android.support.v4.view.ViewPager#setOffscreenPageLimit(int)}. Can use this to call methods on
 * the current positions fragment.
 */
public @Nullable Fragment getFragmentForPosition(int position)
{
    String tag = makeFragmentName(mViewPager.getId(), getItemId(position));
    Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
    return fragment;
}

これはシンプルなソリューションで、ウェブ上のいたるところにある他の2つのソリューションの問題を解決します


6
これは機能しますが、ViewPagerクラスを独自のソースコードにコピーする必要があります。ViewPagerのページャーアダプターの 'instantiateItem()'と 'destroyItem()'に依存すると機能し、フラグメントのライフサイクルを尊重します(これらの2つのメソッドは、保存されたインスタンスの状態からフラグメントが作成されるときにも呼び出されます)。あなたは正しいです。「getItem()」が呼び出されることに依存することは良い考えではなく、プライベートAPIを使用することもどちらでもないということです。
Streets Of Boston

+1これも解決策であり、上記で編集したことに同意します。唯一の違いは、ライフサイクルイベントの発生後にinstantiateItem()まだアクセスされておらず、ライフサイクルイベントのにアクセスされたフラグメントにアクセスしたい場合に、上記が1つ以上のユースケースで機能することです。私が知っている小さな違いですが、プログラムの微妙なバグにつながったので、これを調べています。
ドリ

setOffscreenPageLimit = 1(デフォルト)の場合、FragmentStatePageAdapterは、ビューページにアクセスすると、メモリの内外でフラグメントのスワップを開始します。getItem()への呼び出しにより、再訪問されたページ/フラグメントの新しいインスタンスが作成されます。そのような再訪時に、新しいインスタンスを作成するのではなく、以前に作成したインスタンスを再開するようにシステムに指示する方法はありますか?
カール2014

ページ制限外の場合は、新しいページを作成する必要がありますが、保存された状態で渡されます。古いものを残しておきたい場合は、ページ制限を増やすことができます
Dori

@Dori全くありませんgetItemId(pos)内部FragmentStatePagerAdapter
Jemshit Iskenderov

70

FragmentPagerAdapterに次のメソッドを追加します。

public Fragment getActiveFragment(ViewPager container, int position) {
String name = makeFragmentName(container.getId(), position);
return  mFragmentManager.findFragmentByTag(name);
}

private static String makeFragmentName(int viewId, int index) {
    return "android:switcher:" + viewId + ":" + index;
}

getActiveFragment(0)が機能する必要があります。

これがViewPager https://gist.github.com/jacek-marchwicki/d6320ba9a910c514424dに実装されたソリューションです。何かが失敗した場合、適切なクラッシュログが表示されます。


どうもありがとう:) 。ハンドラーを使用してフラグメントをポストする別の方法でそれを解決しました。これはあまり適切ではありませんが、最終的に問題を解決しました。ところで、あなたはいいです:)
Qun Qin

12
この方法を使用していましたが、API 17(?)に移行すると機能が停止したと思います。私は別の方法をお勧めします。Googleが単純にAPIを公開して、その位置を考慮してViewPagerからフラグメントを取得する場合は、この方法を使用します。
gcl1 2013

2番目のフラグメントを呼び出すときに問題が発生し、メソッドが新しいフラグメントを作成する
Vasil Valchev 2013

2
一部のAPIバージョンのmakeFragmentNameメソッドがプライベート静的文字列に変更されたため、makeFragmentName(int viewId、long id){return "android:switcher:" + viewId + ":" + id; したがって、getActiveFragmentメソッドは次のようになります(2番目の引数の位置の代わりにgetItemIdを使用)public Fragment getActiveFragment(ViewPager container、int position){String name = makeFragmentName(container.getId()、getItemId(position)); mFragmentManager.findFragmentByTag(name);を返します。}
ユージーンポポビッチ2013

1
これは実際に機能しますが、ビューページャーの内部実装を中継し、グーグルが実装を変更すると(そして可能性があります)、悪いことが発生するので、それは本当に危険です。私は本当にグールは、ライブの断片を得るためにそれを利用できるようにすることを願っています
セム

38

別の簡単な解決策:

    public class MyPagerAdapter extends FragmentPagerAdapter {
        private Fragment mCurrentFragment;

        public Fragment getCurrentFragment() {
            return mCurrentFragment;
        }
//...    
        @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            if (getCurrentFragment() != object) {
                mCurrentFragment = ((Fragment) object);
            }
            super.setPrimaryItem(container, position, object);
        }
    }

1
これは、現在のフラグメントのニーズに最適です。
danny117 2014年

現在選択されているFragmentを取得するだけでよい場合は、これだけで十分です。メソッドsetPrimaryItemは、アタッチ時と、現在のアイテムとしてFragmentの内部セットに更新されるたびに設定されます。
Graeme 2015

1
これはいい解決策のように聞こえますが、私がそれを使用できないsetPrimaryItem()呼ばれるように:-( ViewPager.OnPageChangeListener#onPageSelected()
hardysim

21

私はこれにいくつかの答えがあることを知っていますが、多分これは誰かを助けるでしょう。Fragmentからを取得する必要がある場合、私は比較的単純なソリューションを使用しましたViewPager。あなたにActivityまたはFragment保持ViewPager、あなたはすべてのを循環にこのコードを使用することができFragment、それが保持しています。

FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
    Fragment viewPagerFragment = fragmentPagerAdapter.getItem(i);
    if(viewPagerFragment != null) {
        // Do something with your Fragment
        // Check viewPagerFragment.isResumed() if you intend on interacting with any views.
    }
}
  • での自分の位置がわかっている場合FragmentViewPager、を呼び出すだけgetItem(knownPosition)です。

  • でのの位置がわからない場合FragmentViewPager、のFragmentsようなメソッドgetUniqueId()を使用して子供にインターフェースを実装させ、それを使用してそれらを区別することができます。または、すべてFragmentsを循環してクラスタイプを確認することもできます。if(viewPagerFragment instanceof FragmentClassYouWant)

!!! 編集!!!

それぞれが最初に作成される必要がgetItemあるFragmentPagerAdapter場合にのみによって呼び出されることを発見しFragmentました。その後、を使用してリサイクルされているようです。このように、の多くの実装では、に新しいが作成されます。上記の方法を使用すると、これは、内のすべてのアイテムを処理するときに呼び出されるたびに新しいを作成することを意味します。このため、私が使用して、より良いアプローチを発見した各を取得するために(受け入れ答えを使用して)代わりに。これはより完全なソリューションであり、私にとってはうまく機能しています。FragmentsFragmentManagerFragmentPagerAdapter FragmentgetItemFragmentgetItemFragmentPagerAdapterFragmentManagerFragment

FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
    String name = makeFragmentName(mViewPager.getId(), i);
    Fragment viewPagerFragment = getChildFragmentManager().findFragmentByTag(name);
    // OR Fragment viewPagerFragment = getFragmentManager().findFragmentByTag(name);
    if(viewPagerFragment != null) {

        // Do something with your Fragment
        if (viewPagerFragment.isResumed()) {
            // Interact with any views/data that must be alive
        }
        else {
            // Flag something for update later, when this viewPagerFragment
            // returns to onResume
        }
    }
}

そして、このメソッドが必要になります。

private static String makeFragmentName(int viewId, int position) {
    return "android:switcher:" + viewId + ":" + position;
}

1
あなたはただfindFragmentByTag()ですが、フラグメントでタグをどこに設定できますか?
VinceStyling 14年

@vince ViewPagerそれ自体がこれらのタグを設定します。このソリューションは、の「隠された」命名規則を知っていることに依存しているため、脆弱ViewPagerです。Streets of Bostonの答えは、はるかに包括的なソリューションであり、(このアプローチではなく)プロジェクトで使用しています。
Steven Byle

これはうまくいきます!しかし、画面外のListFragmentページを更新する必要があるため、条件付きで「if(viewPagerFragment.isResumed())」を削除しました。次に、ユーザーがListFragmentページに戻ると、すべて新しいデータで更新されます。
JDJ 2014年

10

私の場合、上記の解決策はどれもうまくいきませんでした。

ただし、フラグメントでChild Fragment Managerを使用しているため、以下が使用されました。

Fragment f = getChildFragmentManager().getFragments().get(viewPager.getCurrentItem());

これは、マネージャーのフラグメントがビューページャー項目に対応している場合にのみ機能します。


これは、アクティビティまたはフラグメントが再作成されたときにビューページャーから古いフラグメントを取得するのに最適な答えです。
Smeet

7

ViewPagerから現在のVisibleフラグメントを取得するため。私はこの単純なステートメントを使用していますが、問題なく機能しています。

      public Fragment getFragmentFromViewpager()  
      {
         return ((Fragment) (mAdapter.instantiateItem(mViewPager, mViewPager.getCurrentItem())));
      }

3

最初にすべてのフラグメントのリストを作成して処理しました(List<Fragment> fragments;)の次にそれらをページャーに追加して、現在表示されているフラグメントをより簡単に処理できるようにしました。

そう:

@Override
onCreate(){
    //initialise the list of fragments
    fragments = new Vector<Fragment>();

    //fill up the list with out fragments
    fragments.add(Fragment.instantiate(this, MainFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, MenuFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, StoresFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, AboutFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, ContactFragment.class.getName()));


    //Set up the pager
    pager = (ViewPager)findViewById(R.id.pager);
    pager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager(), fragments));
    pager.setOffscreenPageLimit(4);
}

したがって、これは次のように呼び出すことができます:

public Fragment getFragment(ViewPager pager){   
    Fragment theFragment = fragments.get(pager.getCurrentItem());
    return theFragment;
}

それで、正しいフラグメントにある場合にのみ実行されるifステートメントでそれをチャックできます

Fragment tempFragment = getFragment();
if(tempFragment == MyFragmentNo2.class){
    MyFragmentNo2 theFrag = (MyFragmentNo2) tempFragment;
    //then you can do whatever with the fragment
    theFrag.costomFunction();
}

しかし、それは私のハックとスラッシュのアプローチにすぎませんが、私にとってはうまくいきました。[戻る]ボタンが押されたときに、現在表示されているフラグメントに関連する変更を行うために使用しています。


1
ベストアンサー
Sonu Kumar

3

これは上記のスティーブンの答えに基づいています。これは、親アクティビティに既にアタッチされているフラグメントの実際のインスタンスを返します。

FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) mViewPager.getAdapter();
    for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {

        Fragment viewPagerFragment = (Fragment) mViewPager.getAdapter().instantiateItem(mViewPager, i);
        if(viewPagerFragment != null && viewPagerFragment.isAdded()) {

            if (viewPagerFragment instanceof FragmentOne){
                FragmentOne oneFragment = (FragmentOne) viewPagerFragment;
                if (oneFragment != null){
                    oneFragment.update(); // your custom method
                }
            } else if (viewPagerFragment instanceof FragmentTwo){
                FragmentTwo twoFragment = (FragmentTwo) viewPagerFragment;

                if (twoFragment != null){
                    twoFragment.update(); // your custom method
                }
            }
        }
    }

2

これを行う簡単でクリーンな方法が見つかりませんでした。ただし、ViewPagerウィジェットは、フラグメントをホストする別のViewGroupにすぎません。ViewPagerには、直接の子としてこれらのフラグメントがあります。したがって、(。getChildCount()および.getChildAt()を使用して)それらを反復処理し、探しているフラグメントインスタンスが現在ViewPagerにロードされているかどうかを確認し、その参照を取得できます。たとえば、いくつかの静的な一意のIDフィールドを使用して、フラグメントを区別することができます。

ViewPagerは、ListViewのような仮想化コンテナーであるため、探しているフラグメントをロードしていない可能性があることに注意してください。


1
回答ありがとうございます。adpter.getItem();で取得します。私はAndroidプログラミングの新入生です。本当にありがとうございました。これで、ListFragmentを取得できます。これにフッタービューを追加したいのですが、これをアクティビティで実行してから、logcatを印刷します: "java.lang.IllegalStateException:コンテンツビューがまだ作成されていません。それと。
Qun Qin

1
FragmentActivityにはonAttachFragment()メソッドがあります。この作業をViewPagerのホワイトフラグメントコンテンツに適用しますか?
Vasil Valchev 2013年

2

FragmentPagerAdapterはフラグメントのファクトリです。まだメモリ内にある場合、その位置に基づいてフラグメントを見つけるには、これを使用します。

public Fragment findFragmentByPosition(int position) {
    FragmentPagerAdapter fragmentPagerAdapter = getFragmentPagerAdapter();
    return getSupportFragmentManager().findFragmentByTag(
            "android:switcher:" + getViewPager().getId() + ":"
                    + fragmentPagerAdapter.getItemId(position));
}

v4サポートAPIのサンプルコード。


onresume()でnullを返します。なぜそれを修正するための鍬やアイデアがありますか?
seema

2

あなたがいない通話に必要なgetItem()の参照を取得するために、後の段階で、または他のいくつかの方法でFragmentホストされている内部をViewPager。内部のデータを更新したい場合はFragment、このアプローチを使用してください:ViewPagerを動的に更新しますか?

重要なのは、内部に新しいデータを設定してAdaperを呼び出すことです。notifyDataSetChanged()これにより、が呼び出されgetItemPosition()、自分の参照が渡さFragmentれ、更新する機会が与えられます。他のすべての方法では、自分自身または他のハックへの参照を維持する必要がありますが、これは良い解決策ではありません。

@Override
public int getItemPosition(Object object) {
    if (object instanceof UpdateableFragment) {
        ((UpdateableFragment) object).update(xyzData);
    }
    //don't return POSITION_NONE, avoid fragment recreation. 
    return super.getItemPosition(object);
}

ここでは理解できません。getItemPosition()を使用するにはFragmentの参照が必要なので、getItemPositionを使用しない方がいいでしょう。

getItemPosition()アダプタのメソッドです。直接呼び出すことはありません。あなたはあなたのアダプターのリファレンスを持っているので、あなたはあなたのsのリファレンスを渡すことによってあなたのアダプターadapter.notifyDataSetChanged()を呼び出しgetItemPosition()ますFragment。あなたはここにアクションで完全な実装を見ることができますstackoverflow.com/questions/19891828/...
M-WaJeEh

私はそれを読みましたが、それでもわかりません。それらに対して呼び出しを行うには、これらのフラグメントへの直接参照が必要ですよね?あなたはハックとしてそれを言及しますが、私は代替案を見ません。adapter.getItem(i)は明らかに機能しません。

2
わかりやすくするために回答を更新しました。もちろん、参照を更新するには参照が必要ですFragmentが、参照を取得する方法は議論の余地があります。他のソリューションは、すべてのフラグメントが自分自身を再作成するのFragmentManagerと同様の文字列を使用する"android:switcher:"+idか、それから 戻ることで参照を取得します。POSITION_NONEgetItemosition()
M-WaJeEh 2013

おかげで、これはずっと意味があり、私の経験と一致しています(そのため、私は何か間違ったことをしているのではないかもしれません)。

2

FragmentPagerAdapterViewPagerアダプタークラスに拡張する必要があります。
あなたが使用する場合、あなたはFragmentStatePagerAdapterそれFragmentによってあなたを見つけることができませんID

public static String makeFragmentName(int viewPagerId, int index) {
  return "android:switcher:" + viewPagerId + ":" + index;
}

この方法の使い方:-

Fragment mFragment = ((FragmentActivity) getContext()).getSupportFragmentManager().findFragmentByTag(
       AppMethodUtils.makeFragmentName(mViewPager.getId(), i)
);
InterestViewFragment newFragment = (InterestViewFragment) mFragment;


1

最善の解決策は、SmartFragmentStatePagerAdapterと呼ばれる、CodePathで作成した拡張機能を使用することです。そのガイドに従って、これにより、ViewPagerからフラグメントと現在選択されているフラグメントを簡単に取得できるようになります。また、アダプター内に埋め込まれたフラグメントのメモリーをより適切に管理します。


0

最も簡単で最も簡潔な方法。のすべてのフラグメントViewPagerが異なるクラスのものである場合、次のようにしてそれらを取得および区別できます。

public class MyActivity extends Activity
{

    @Override
    public void onAttachFragment(Fragment fragment) {
        super.onAttachFragment(fragment);
        if (fragment.getClass() == MyFragment.class) {
            mMyFragment = (MyFragment) fragment;
        }
    }

}

ViewPagerを使用すると複数のフラグメントがアタッチされるため、これも誤りです。現在のページフラグメントがあり、その左側と右側に1つずつあります。これにより、ユーザーは、ユーザーがそれらに到達したときにのみ初期化する必要なく、それらの間をスライドできます。
Android開発者

0

私はこれを少し異なるアプローチで簡単に実装しました。

私のカスタムFragmentAdapter.getItemメソッドは、新しいMyFragment()ではなく、FragmentAdapterコンストラクターで作成されたMyFragmentのインスタンスを返しました。

私のアクティビティでは、アダプタからフラグメントを取得し、それがinstanceOf必要なフラグメントであるかどうかを確認してから、必要なメソッドをキャストして使用します。


0

/values/integers.xmlに整数のリソースIDを作成します

<integer name="page1">1</integer>
<integer name="page2">2</integer>
<integer name="page3">3</integer>

次に、PagerAdapter getItem関数で:

public Fragment getItem(int position) {

        Fragment fragment = null;

        if (position == 0) {
            fragment = FragmentOne.newInstance();
            mViewPager.setTag(R.integer.page1,fragment);

        }
        else if (position == 1) {

            fragment = FragmentTwo.newInstance();
            mViewPager.setTag(R.integer.page2,fragment);

        } else if (position == 2) {

            fragment = FragmentThree.newInstance();
            mViewPager.setTag(R.integer.page3,fragment);

        }

        return fragment;
        }

次に、アクティビティでこの関数を記述して、フラグメント参照を取得します。

private Fragment getFragmentByPosition(int position) {
    Fragment fragment = null;

    switch (position) {
        case 0:
            fragment = (Fragment) mViewPager.getTag(R.integer.page1);
            break;

        case 1:

            fragment = (Fragment) mViewPager.getTag(R.integer.page2);
            break;

        case 2:
            fragment = (Fragment) mViewPager.getTag(R.integer.page3);
            break;
            }

            return fragment;
    }

上記の関数を呼び出してフラグメント参照を取得し、カスタムフラグメントにキャストします。

Fragment fragment = getFragmentByPosition(position);

        if (fragment != null) {
                    FragmentOne fragmentOne = (FragmentOne) fragment;
                    }

0

フラグメントマネージャーでフラグメントを反復する簡単な方法。public static PlaceholderFragment newInstance(int sectionNumber)に配置されたセクション位置引数を持つviewpagerを見つけます 。

public PlaceholderFragment getFragmentByPosition(Integer pos){
    for(Fragment f:getChildFragmentManager().getFragments()){
        if(f.getId()==R.id.viewpager && f.getArguments().getInt("SECTNUM") - 1 == pos) {
            return (PlaceholderFragment) f;
        }
    }
    return null;
}

0

断片的に

public int getArgument(){
   return mPage;
{
public void update(){

}

FragmentActivity

List<Fragment> fragments = getSupportFragmentManager().getFragments();
for(Fragment f:fragments){
    if((f instanceof PageFragment)&&(!f.isDetached())){
          PageFragment pf = (PageFragment)f;   
          if(pf.getArgument()==pager.getCurrentItem())pf.update();
    }
}

0

TabLayoutにはFragmentの複数のタブがあります。フラグメントのインデックスを使用して、タグによってフラグメントを見つけることができます。

例のために。Fragment1のインデックスは0であるため、findFragmentByTag()メソッドで、追加できるフラグメントトランザクションを使用してViewpager.afterのタグを渡し、フラグメントを置き換えます。

String tag = "android:switcher:" + R.id.viewPager + ":" + 0; Fragment1 f = (Fragment1) getSupportFragmentManager().findFragmentByTag(tag);


-1

FragmentStatePagerAdapter私が解決策に資金を提供するアダプターについてわかりました:

あなたのFragmentActivityで:

ActionBar mActionBar = getSupportActionBar(); 
mActionBar.addTab(mActionBar.newTab().setText("TAB1").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment1.class.getName())));
mActionBar.addTab(mActionBar.newTab().setText("TAB2").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment2.class.getName())));
mActionBar.addTab(mActionBar.newTab().setText("TAB3").setTabListener(this).setTag(Fragment.instantiate(this, MyFragment3.class.getName())));

viewPager = (STViewPager) super.findViewById(R.id.viewpager);
mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager(), mActionBar);
viewPager.setAdapter(this.mPagerAdapter);

そして、クラスFragmentActivityにメソッドを作成します-そのメソッドがあなたのFragmentへのアクセスを提供するので、あなたはそれにあなたが望むフラグメントの位置を与える必要があるだけです:

public Fragment getActiveFragment(int position) {
String name = MyPagerAdapter.makeFragmentName(position);
return getSupportFragmentManager().findFragmentByTag(name);
}

あなたのアダプターで:

public class MyPagerAdapter extends FragmentStatePagerAdapter {

private final ActionBar actionBar;
private final FragmentManager fragmentManager;

public MyPagerAdapter(FragmentManager fragmentManager, com.actionbarsherlock.app.ActionBarActionBar mActionBar) {super(fragmentManager);
this.actionBar = mActionBar;
this.fragmentManager = fragmentManager;
}

@Override
public Fragment getItem(int position) {
getSupportFragmentManager().beginTransaction().add(mTchatDetailsFragment, makeFragmentName(position)).commit();
return (Fragment)this.actionBar.getTabAt(position);
}

@Override
public int getCount() {
return this.actionBar.getTabCount();
}

@Override
public CharSequence getPageTitle(int position) {
return this.actionBar.getTabAt(position).getText();
}

private static String makeFragmentName(int viewId, int index) {
return "android:fragment:" + index;
}

}

-1
Fragment yourFragment = yourviewpageradapter.getItem(int index);

indexfragment1最初に追加したようにアダプターのフラグメントの場所なので、fragment1パスindexは0として取得し、残りは同様に残ります。

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