Android FragmentStatePagerAdapter,如何标记片段以便以后找到它

Héc*_*ena 22 android android-viewpager

使用时,FragmentStatePageAdapter我得到这样的片段:

    @Override
    public Fragment getItem(int position) {
        return new SuperCoolFragment();
    }
Run Code Online (Sandbox Code Playgroud)

但是,稍后我的代码我需要找到这个片段来设置属性.在我使用片段的应用程序的其他一些部分,我基本上标记它们并使用它们来查找它们,findFragmentByTag(TAG)但现在我不知道该怎么做.

如何使用FragmentStatePageAdapter?找到碎片?

Fra*_*ank 48

*编辑*

正如@ElliotM指出的那样,有一个更好的解决方案.无需更改适配器中的任何内容,只需获取片段:

Fragment myFragment = (Fragment) adapter.instantiateItem(viewPager, viewPager.getCurrentItem());
Run Code Online (Sandbox Code Playgroud)

*旧解决方案*

最好的选择是这里的第二个解决方案:http: //tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part-ii.html

简而言之:您可以跟踪所有"活动"片段页面.在这种情况下,您将跟踪ViewPager使用的FragmentStatePagerAdapter中的片段页面.

public Fragment getItem(int index) {
    Fragment myFragment = MyFragment.newInstance();
    mPageReferenceMap.put(index, myFragment);
    return myFragment;
}
Run Code Online (Sandbox Code Playgroud)

为了避免保留对"非活动"片段页面的引用,我们需要实现FragmentStatePagerAdapter的destroyItem(...)方法:

public void destroyItem(View container, int position, Object object) {
    super.destroyItem(container, position, object);
    mPageReferenceMap.remove(position);
}
Run Code Online (Sandbox Code Playgroud)

...当您需要访问当前可见的页面时,您可以调用:

int index = mViewPager.getCurrentItem();
MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
MyFragment fragment = adapter.getFragment(index);
Run Code Online (Sandbox Code Playgroud)

... MyAdapter的getFragment(int)方法如下所示:

public MyFragment getFragment(int key) {
    return mPageReferenceMap.get(key);
}
Run Code Online (Sandbox Code Playgroud)

---编辑:

还要在适配器中添加此项,以便在更改方向后:

/**
 * After an orientation change, the fragments are saved in the adapter, and
 * I don't want to double save them: I will retrieve them and put them in my
 * list again here.
 */
@Override
public Object instantiateItem(ViewGroup container, int position) {
    MyFragment fragment = (MyFragment) super.instantiateItem(container,
            position);
    mPageReferenceMap.put(position, fragment);
    return fragment;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果从头开始销毁并重新创建主机活动,则此方法无效.不会调用getItem(index),并且您的mPageReferenceMap将为空.转到开发人员选项 - >"不要保留活动"并亲自查看. (2认同)

Lan*_*lot 15

我找到了另一种方法,不确定使用它是否有任何问题,对我来说似乎没问题.

我正在检查FragmentStatePageAdapter的代码,我看到了这个方法:

@Override
52     public Object More ...instantiateItem(View container, int position) {
53         // If we already have this item instantiated, there is nothing
54         // to do.  This can happen when we are restoring the entire pager
55         // from its saved state, where the fragment manager has already
56         // taken care of restoring the fragments we previously had instantiated.
57         if (mFragments.size() > position) {
58             Fragment f = mFragments.get(position);
59             if (f != null) {
60                 return f;
61             }
62         }
63 
64         if (mCurTransaction == null) {
65             mCurTransaction = mFragmentManager.beginTransaction();
66         }
67 
68         Fragment fragment = getItem(position);
69         if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
70         if (mSavedState.size() > position) {
71             Fragment.SavedState fss = mSavedState.get(position);
72             if (fss != null) {
73                 fragment.setInitialSavedState(fss);
74             }
75         }
76         while (mFragments.size() <= position) {
77             mFragments.add(null);
78         }
79         fragment.setMenuVisibility(false);
80         mFragments.set(position, fragment);
81         mCurTransaction.add(container.getId(), fragment);
82 
83         return fragment;
84     }
Run Code Online (Sandbox Code Playgroud)

您可以使用此方法获取已为该特定位置设置的片段.所以如果你想让Fragment在第1位,你只需要打电话:

myFragmentStatePageAdpater.instantiateItem(null, 1)
Run Code Online (Sandbox Code Playgroud)

希望有所帮助


Chr*_*acy 5

我通过添加一个getItemTag(int position)函数来实现这一点FragmentStatePagerAdapter.如果有其他人想要使用此路线,则可以在此处获得更新文件的插入版本.


小智 -10

创建一个支架来容纳新的 SuperCoolFragment 对象。然后标记并返回持有者对象。

@Override
public Fragment getItem(int position) {
    SuperCoolFragment superCoolFragment = new SuperCoolFragment();
    superCoolFragment.setTag(YOUR_TAG);
    return superCoolFragment;
}
Run Code Online (Sandbox Code Playgroud)

  • 我没有看到 Fragment.setTag() 函数。不过,您可以在提交 FragmentTransaction 时添加标签。 (2认同)