首页 文章

Android FragmentStatePagerAdapter

提问于
浏览
17

我正在使用this example使用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);
        }
    }

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

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

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

5 回答

  • 5

    我已经实现了类似于你拥有的东西 . 我像这样扩展了 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;
        }
    }
    

    注意我已经在构造函数中添加了一个参数来传递 FragmentFragment 对象 . 这样,此类的 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();
                }
            });
    
        }
    
    }
    

    通过访问变量"fragments",您可以访问以前创建的 Fragment ,以便您可以运行该 Fragment 的方法 .

  • 39

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

    如果你看一下source of FragmentStatePagerAdapter.instantiateItem(),你会发现 instantiateItem() 为你处理这个逻辑,因此 getItem() 的实现应该总是返回一个新实例 .

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

    Fragment f = (Fragment) getAdapter().instantiateItem(this, getCurrentItem());
    
  • 3

    虽然@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;
        }
    
  • 7
    public class MyPagerAdapter extends FragmentStatePagerAdapter {
        final Context m_context;
        final WeakReference<Fragment>[] m_fragments;
    
        public DetailPagerAdapter(FragmentManager fm) {
            super(fm);
            m_context = ...
                    m_fragments = new WeakReference[enter size here];
        }
    
        @Override
        public Fragment getItem(int position) {
            final Fragment fragment = instantiate your fragment;
            m_fragments[position] = new WeakReference<Fragment>(fragment);
            return fragment;
        }
    
        @Override
        public int getCount() {
            return ...
        }
    
        public Fragment getFragment(final int position) {
            return m_fragments[position] == null ? null :
                m_fragments[position].get();
        }
    }
    
  • 0

    不需要修改FragmentPagerAdapter,因为片段由FragmentManager缓存 . 所以你必须要在里面找到它 . 使用此函数通过寻呼机适配器位置查找片段 .

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

    v4支持api的示例代码 .

相关问题