Android FragmentStatePagerAdapter

后端 未结 5 1330
太阳男子
太阳男子 2021-02-01 18:02

I\'m working with a FragmentStatePagerAdapter using this example.

The MyAdapter class is implemented as follows:

public static class MyAdapter extends Fr         


        
相关标签:
5条回答
  • 2021-02-01 18:21

    Do not need modify the FragmentPagerAdapter, because fragments are cached by the FragmentManager. So you must need find inside it. Use this function to find the fragment by pager adapter position.

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

    Sample code for v4 support api.

    0 讨论(0)
  • 2021-02-01 18:22
    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 讨论(0)
  • 2021-02-01 18:24

    I have implemented something similar to what you have. I extended the FragmentPagerAdapter class like so:

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

    Notice I have added an argument to the constructor to pass in the List of Fragment objects. This way the getItem() method of this class can return any class that extends Fragment or any of its subclasses and not just one specific class ArrayListFragment like you have done.

    In the Activity where I instantiate my subclass of FragmentPagerAdapter I have passed in the list of Fragment objects:

    Class the instantiates the 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();
                }
            });
    
        }
    
    }
    

    By accessing the variable "fragments", you can access a previously created Fragment so that you can run methods of that Fragment.

    0 讨论(0)
  • 2021-02-01 18:35

    While @imiric's solution is very concise, it still bothers me that it requires knowledge of the implementation of the class. My solution involves adding the following to your adapter, which should behave nicely with a FragmentStatePagerAdapter possibly destroying fragments:

        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;
        }
    
    0 讨论(0)
  • 2021-02-01 18:39

    I think the solution is much simpler than the answers provided.

    If you take a look at the source of FragmentStatePagerAdapter.instantiateItem(), you'll notice that instantiateItem() handles this logic for you, and thus your implementation of getItem() should always return a new instance.

    So in order to return an existing Fragment, simply do (assuming you're calling from ViewPager):

    Fragment f = (Fragment) getAdapter().instantiateItem(this, getCurrentItem());
    
    0 讨论(0)
提交回复
热议问题