Update data in ListFragment as part of ViewPager

后端 未结 10 1852
一整个雨季
一整个雨季 2020-11-22 07:55

I\'m using the v4 compatibility ViewPager in Android. My FragmentActivity has a bunch of data which is to be displayed in different ways on different pages in my ViewPager.

相关标签:
10条回答
  • 2020-11-22 08:33

    Also works without problems:

    somewhere in page fragment's layout:

    <FrameLayout android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone" android:id="@+id/fragment_reference">
         <View android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/>
    </FrameLayout>
    

    in fragment's onCreateView():

    ...
    View root = inflater.inflate(R.layout.fragment_page, container, false);
    ViewGroup ref = (ViewGroup)root.findViewById(R.id.fragment_reference);
    ref.setTag(this);
    ref.getChildAt(0).setTag("fragment:" + pageIndex);
    return root;
    

    and method to return Fragment from ViewPager, if exists:

    public Fragment getFragment(int pageIndex) {        
            View w = mViewPager.findViewWithTag("fragment:" + pageIndex);
            if (w == null) return null;
            View r = (View) w.getParent();
            return (Fragment) r.getTag();
    }
    
    0 讨论(0)
  • 2020-11-22 08:33

    I want to give my approach in case it can help anyone else:

    This is my pager adapter:

     public class CustomPagerAdapter extends FragmentStatePagerAdapter{
        private Fragment[] fragments;
    
        public CustomPagerAdapter(FragmentManager fm) {
            super(fm);
            fragments = new Fragment[]{
                    new FragmentA(),
                    new FragmentB()
            };
        }
    
        @Override
        public Fragment getItem(int arg0) {
            return fragments[arg0];
        }
    
        @Override
        public int getCount() {
            return fragments.length;
        }
    
    }
    

    In my activity I have:

    public class MainActivity {
            private ViewPager view_pager;
            private CustomPagerAdapter adapter;
    
    
            @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            adapter = new CustomPagerAdapter(getSupportFragmentManager());
            view_pager = (ViewPager) findViewById(R.id.pager);
            view_pager.setAdapter(adapter);
            view_pager.setOnPageChangeListener(this);
              ...
             }
    
    }
    

    Then to get the current fragment what I do is:

    int index = view_pager.getCurrentItem();
    Fragment currentFragment = adapter.getItem(index);
    
    0 讨论(0)
  • 2020-11-22 08:40

    If you ask me, the second solution on the below page, keeping track of all the "active" fragment pages, is better: http://tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part-ii.html

    The answer from barkside is too hacky for me.

    you keep track of all the "active" fragment pages. In this case, you keep track of the fragment pages in the FragmentStatePagerAdapter, which is used by the ViewPager.

    private final SparseArray<Fragment> mPageReferences = new SparseArray<Fragment>();
    
    public Fragment getItem(int index) {
        Fragment myFragment = MyFragment.newInstance();
        mPageReferences.put(index, myFragment);
        return myFragment;
    }
    

    To avoid keeping a reference to "inactive" fragment pages, we need to implement the FragmentStatePagerAdapter's destroyItem(...) method:

    public void destroyItem(View container, int position, Object object) {
        super.destroyItem(container, position, object);
        mPageReferences.remove(position);
    }
    

    ... and when you need to access the currently visible page, you then call:

    int index = mViewPager.getCurrentItem();
    MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
    MyFragment fragment = adapter.getFragment(index);
    

    ... where the MyAdapter's getFragment(int) method looks like this:

    public MyFragment getFragment(int key) {
        return mPageReferences.get(key);
    }
    

    "

    0 讨论(0)
  • 2020-11-22 08:41

    Barkside's answer works with FragmentPagerAdapter but doesn't work with FragmentStatePagerAdapter, because it doesn't set tags on fragments it passes to FragmentManager.

    With FragmentStatePagerAdapter it seems we can get by, using its instantiateItem(ViewGroup container, int position) call. It returns reference to fragment at position position. If FragmentStatePagerAdapter already holds reference to fragment in question, instantiateItem just returns reference to that fragment, and doesn't call getItem() to instantiate it again.

    So, suppose, I'm currently looking at fragment #50, and want to access fragment #49. Since they are close, there's a good chance the #49 will be already instantiated. So,

    ViewPager pager = findViewById(R.id.viewpager);
    FragmentStatePagerAdapter a = (FragmentStatePagerAdapter) pager.getAdapter();
    MyFragment f49 = (MyFragment) a.instantiateItem(pager, 49)
    
    0 讨论(0)
提交回复
热议问题