Android FragmentStatePagerAdapter

mra*_*tor 21 android android-fragments fragmentpageradapter

我正在使用这个例子使用FragmentStatePagerAdapter .

MyAdapter类实现如下:

public static class MyAdapter extends FragmentStatePagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

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

        @Override
        public Fragment getItem(int position) {
            return ArrayListFragment.newInstance(position);
        }
    }
Run Code Online (Sandbox Code Playgroud)

ListFragment类包含以下创建新实例的方法:

    /**
     * Create a new instance of CountingFragment, providing "num"
     * as an argument.
     */
    static ArrayListFragment newInstance(int num) {
        ArrayListFragment f = new ArrayListFragment();

        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putInt("num", num);
        f.setArguments(args);

        return f;
    }
Run Code Online (Sandbox Code Playgroud)

当我在我的活动中创建一个新的片段状态寻呼机适配器时,getItem会调用它,然后调用newInstanceListFragment类中的方法.当我想创建一个新片段时,这很棒.

但是我不清楚如何修改getItem(如果需要的话)获取片段对象(如果它已经存在)并且用户页面从例如第2页到第1页.我希望我的Activity可以检索现有的,以前的创建了片段,以便它可以运行一个内部类AsyncMethod,它位于片段类中.

imi*_*ric 44

我认为解决方案比提供的答案简单得多.

如果您查看源代码FragmentStatePagerAdapter.instantiateItem(),您会注意到instantiateItem()为您处理此逻辑,因此您的实现getItem()应始终返回一个新实例.

因此,为了返回现有的片段,只需执行(假设您正在调用ViewPager):

Fragment f = (Fragment) getAdapter().instantiateItem(this, getCurrentItem());
Run Code Online (Sandbox Code Playgroud)

  • 最好的答案是隐藏在底部!public void onPageScrolled(int i,float v,int i2){Fragment fragment =(Fragment)imagePagerAdapter.instantiateItem(mImageViewPager,i); (4认同)
  • 只有在查看源代码后,我才意识到问题的逻辑.并且看到这是页面上唯一合乎逻辑的答案.非常感谢你. (2认同)

qix*_*qix 8

虽然@imiric的解决方案非常简洁,但它仍然困扰我,它需要了解类的实现.我的解决方案涉及将以下内容添加到您的适配器,它应该与FragmentStatePagerAdapter很好地破坏片段:

    private SparseArray<WeakReference<Fragment>> mFragments = new SparseArray<>();

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment f = (Fragment) super.instantiateItem(container, position);
        mFragments.put(position, new WeakReference<>(f));  // Remember what fragment was in position
        return f;
    }

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

    public Fragment getFragment(int position) {
        WeakReference<Fragment> ref = mFragments.get(position);
        Fragment f = ref != null ? ref.get() : null;
        if (f == null) {
            Log.d(TAG, "fragment for " + position + " is null!");
        }
        return f;
    }
Run Code Online (Sandbox Code Playgroud)

  • 您不应该保留对Fragments的引用,因为它们可以随时被销毁和重新创建.如果发生这种情况,您的引用将无效,并且无法对垃圾进行垃圾回收. (3认同)

too*_*o42 6

我已经实现了类似于你所拥有的东西。我FragmentPagerAdapter像这样扩展了课程:

public class ContactsFragmentPagerAdapter extends FragmentPagerAdapter {
    ActionBar mActionBar;
    private List<Fragment> mFragments;

    public ContactsFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        mFragments = fragments;
    }

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

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    public void setActionBar(ActionBar bar) {
        mActionBar = bar;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我向构造函数添加了一个参数以传入ListofFragment对象。这样,此类的getItem()方法可以返回任何扩展类Fragment或其任何子类,而不仅仅是ArrayListFragment像您所做的那样只返回一个特定类。

Activity我实例化我的子类的地方,FragmentPagerAdapter我已经传入了Fragment对象列表:

类实例化 FragmentPagerAdapter

public final class ContactManager extends Activity {
    private ContactsFragmentPagerAdapter mAdapter;
    private ViewPager mPager;
    public ActionBar mActionBar;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.contact_manager);

        List<Fragment> fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this, ContactsListFragment.class.getName()));
        fragments.add(Fragment.instantiate(this, GroupsListFragment.class.getName()));
        mAdapter = new ContactsFragmentPagerAdapter(this.getFragmentManager(), fragments);

        mPager = (ViewPager) findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);

        mPager.setOnPageChangeListener(new OnPageChangeListener() {
            @Override
            public void onPageScrollStateChanged(int arg0) {}

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {}

            @Override
            public void onPageSelected(int arg0) {
                mActionBar.getTabAt(arg0).select();
            }
        });

    }

}
Run Code Online (Sandbox Code Playgroud)

通过访问变量“fragments”,您可以访问先前创建FragmentFragment.

  • 如果有一个解决方案不让所有片段始终实例化以与 `FragmentStatePagerAdapter` 一起工作,那就太好了,因为这确实是该适配器的全部意义。 (19认同)