从ViewPager检索片段


248

我正在使用和ViewPager一起FragmentStatePagerAdapter托管三个不同的片段:

  • [片段1]
  • [Fragment2]
  • [Fragment3]

当我想Fragment1ViewPagerFragmentActivity

有什么问题,我该如何解决?

Answers:


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,然后需要用新的更新它FragmentManager裁判?
史蒂芬·拜尔

10
如果我没记错的话(应该检查一下),则不会调用getItem方法(如您所知),但是对于旋转后框架要还原的每个Fragment都会调用InstantiateItem方法。
2013年

6
是的,我已经确认getItem不会对旋转再次调用(对于已创建的任何碎片),因为FragmentManager恢复了Fragments它在寻呼机中所处的状态。如果instantiateItem在每个Fragment恢复时都被调用,那么该解决方案实际上比我的解决方案或公认的答案更安全,更可靠。我会考虑自己尝试一下。
史蒂芬·拜尔

6
@Dori我没有打破它。我的解决方案没有使用'getItem()'调用的结果。相反,它使用的是从“ instantiateItem()”调用中存储的结果。而且片段的生命周期没有中断,因为在“ destroyItem()”调用中,存储的片段将从稀疏数组中删除。
波士顿街头

85

要从ViewPager中获取片段,可以在此处以及其他相关的SO线程/博客中找到很多答案。我见过的每个人都很沮丧,他们通常似乎属于以下两种类型之一。还有一些其他的解决方案有效,如果你只想要抓住当前片段,像这样在此线程的其他答案。

如果使用,FragmentPagerAdapter请参见下文。如果使用FragmentStatePagerAdapter它的价值看这个。捕获不是FragmentStateAdapter中的当前索引的索引并没有它的本质那样有用,因为这些索引将被完全删除,从而超出了视图范围/超出了ScreenScreenLimit的范围。

不幸的道路

错误:保持碎片自己的内部列表,添加时FragmentPagerAdapter.getItem()被调用

  • 通常使用SparseArrayMap
  • 我没有看到许多说明生命周期事件的示例,因此此解决方案很脆弱。正如getItem仅在页面中第一次滚动浏览(或在您的ViewPager.setOffscreenPageLimit(x)> 0时获得)那样ViewPager,如果托管Activity/ Fragment被终止或重新启动,则在SpaseArray重新创建自定义FragmentPagerActivity时内部将被擦除,但是在后台ViewPagers内部片段将被重新创建,并且getItem被要求任何的指标,所以从指数得到片段的能力将永远消失。您可以通过保存并通过FragmentManager.getFragment()和还原这些片段引用来解决putFragment此问题, 但这会变得混乱IMHO。

错误:构造与引擎盖下使用的标签ID匹配的标签ID,FragmentPagerAdapter并使用此ID检索页面中的FragmentsFragmentManager

  • 这更好,因为它可以解决第一个内部阵列解决方案中的丢失片段引用问题,但是正如上面和网上其他地方的答案所正确指出的那样-感觉很棘手,因为它是内部可能的私有方法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;
}

这是一个简单的解决方案,解决了网络上到处可见的其他两个解决方案中的问题


6
这将起作用,但是需要将ViewPager类复制到您自己的源代码中。依靠ViewPager的寻呼机适配器的'instantiateItem()'和'destroyItem()'将起作用,并将遵守片段的生命周期(当从save-instance-state状态创建片段时,也会调用这两种方法)。没错,依靠'getItem()'调用不是一个好主意,而使用私有API也不是。
波士顿街道

+1我同意这也是一种解决方案,并已在上面进行了编辑。唯一的区别是,以上内容在一个用例中起作用,即instantiateItem()您要访问生命周期事件发生尚未访问且生命周期事件之前已访问过的片段。我知道一个很小的差异,但是它导致了我的程序中的一个细微错误,因此我对此进行了研究。
多丽2014年

如果setOffscreenPageLimit = 1(默认值),则在访问视图页面时,FragmentStatePageAdapter将开始在内存中和内存中交换片段。通过调用getItem(),将创建重新访问的页面/片段的新实例。重新访问后,是否有一种方法指示系统恢复以前创建的实例,而不是创建一个新实例?
2014年

如果超出页面限制,则必须创建一个新页面-但会传递已保存状态。如果想保留旧的页面,则可以增加页数限制
Dori 2014年

@Dori没有getItemId(pos)内心FragmentStatePagerAdapter
Jemshit Iskenderov 2015年

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中检索Fragment,则更希望使用该方法。
gcl1 2013年

我在调用第二个片段时遇到问题,该方法创建了一个新片段
Vasil Valchev

2
由于某些API版本的makeFragmentName方法已更改为私有静态String makeFragmentName(int viewId,long id){返回“ android:switcher:” + viewId +“:” + id; },因此getActiveFragment方法现在应如下所示(使用getItemId代替第二个参数的位置)public Fragment getActiveFragment(ViewPager container,int position){字符串名称= makeFragmentName(container.getId(),getItemId(position)); 返回mFragmentManager.findFragmentByTag(name); }
Eugene Popovich

1
它确实可以工作,但是确实很危险,因为它依赖于视图传呼器的内部实现,如果Google更改实现(并且他们可以这样做),将会发生不好的事情。我真的希望goole能够提供现场片段
13年

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

如果您需要做的就是获取当前选定的Fragment,这就是您所需要的-方法setPrimaryItem设置在Attach上,并且在每次更新到Fragment的内部集上作为当前项设置。
Graeme

1
这听起来像是一个不错的解决方案,但是我无法使用它后被setPrimaryItem()调用:-( ViewPager.OnPageChangeListener#onPageSelected()
hardysim

21

我知道这有一些答案,但这也许会对某人有所帮助。当我需要Fragment从我的网站上获取一个时,我使用了一个相对简单的解决方案ViewPager。在您ActivityFragment持有的中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.
    }
}
  • 如果你知道你的位置 Fragment在中ViewPager,可以致电getItem(knownPosition)

  • 如果您不知道自己Fragment在中的位置ViewPager,则可以让您的孩子使用Fragments诸如的方法来实现接口getUniqueId(),并使用该接口来区分它们。或者,您可以遍历所有内容Fragments并检查类的类型,例如if(viewPagerFragment instanceof FragmentClassYouWant)

!!! 编辑!

我发现getItem只有在第一次需要创建FragmentPagerAdapter每个对象时才会被a调用,此后,似乎使用进行了回收。这样一来,许多的实现创造新的以s 。使用我的上述方法,这意味着当我们遍历中的所有项目时,每次调用new 时都将创建new 。因此,我找到了一种更好的方法,使用来代替每个(使用公认的答案)。这是一个更完整的解决方案,对我来说一直很好。FragmentFragmentsFragmentManagerFragmentPagerAdapter 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
您只是找到FragmentByTag(),但是我们可以在哪里设置带有片段的TAG?
VinceStyling 2014年

@vince ViewPager本身设置那些标签。该解决方案非常脆弱,因为它依赖于了解的“隐藏”命名约定ViewPager。波士顿街头的答案是一个更为全面的解决方案,我现在在我的项目中使用它(而不是这种方法)。
史蒂文·拜尔2014年

这很棒!但是我删除了“ if(viewPagerFragment.isResumed())”条件,因为我需要更新屏幕外的ListFragment页面。然后,当用户返回到ListFragment页面时,将全部使用新数据进行更新。
JDJ

10

就我而言,以上解决方案均无效。

但是,由于我在片段中使用了子片段管理器,因此使用了以下内容:

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

仅当您在Manager中的片段与viewpager项相对应时,这才起作用。


当重新创建活动或片段时,这是从视图寻呼机获取旧片段的完美答案。
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();
}

但这只是我的hack和slash方法,但对我有用,当按下后退按钮时,我确实使用它确实使更改更改为当前显示的片段。


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,并向其中添加footerView,同时在Activity中执行此操作,然后在logcat上打印:“ java.lang.IllegalStateException:尚未创建内容视图。”。我知道为什么,但遇到困难用它。
Qun Qin

1
FragmentActivity具有onAttachFragment()方法,该工作是否适用于ViewPager片段内容?
Vasil Valchev

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 2014年

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

我在这里不明白,您需要使用Fragment的引用才能使用getItemPosition(),所以您也可能不使用getItemPosition,是吗?

getItemPosition()是适配器中的一种方法。您不会直接调用它。您有适配器的引用,因此您可以调用adapter.notifyDataSetChanged(),而后者将getItemPosition()通过传递Fragments的引用来调用适配器。你可以看到在行动全面实施这里stackoverflow.com/questions/19891828/...
M-WaJeEh

我已经读完了,但仍然不明白。为了对它们进行调用,您仍然需要直接引用这些片段,对吗?您提到这是一种骇客行为,但我没有其他选择。adapter.getItem(i)显然无法正常工作。

2
好的,我已经更新了我的答案以阐明更多信息。当然需要参考来更新a,Fragment但是如何获得参考却是有争议的。其他的解决方案,从获得参考FragmentManager使用字符串相似 "android:switcher:"+id或返回POSITION_NONEgetItemosition()导致所有片段意趣盎然。
M-WaJeEh

谢谢,这更有意义,并且与我的经验相符(所以我可能做错了,哈)。

2

必须扩展FragmentPagerAdapter到ViewPager适配器类中。
如果使用,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

最好的解决方案是使用我们在CodePath创建的扩展名为SmartFragmentStatePagerAdapter。遵循该指南,这使得从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时会附着多个片段。当前的页面片段在其左侧,而在其右侧则是一个。这允许用户在它们之间滑动而不必仅在用户到达它们时对其进行初始化。
android开发人员

0

我用一些不同的方法实现了这个简单。

我的自定义FragmentAdapter.getItem方法返回的不是new 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

在片段管理器中迭代片段的简单方法。查找具有节位置参数的viewpager,将其放置在 公共静态PlaceholderFragment newInstance(int sectionNumber)中

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的选项卡。您可以使用片段的索引按Tag查找片段。

对于前。Fragment1的索引为0,因此在findFragmentByTag()方法中,传递Viewpager的标签。使用fragmentTransaction之后,您可以添加,替换片段。

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

index是适配器中片段的位置,就像您fragment1首先添加的那样,后退fragment1通过index为0,以此类推

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.