Android: Viewpager and FragmentStatePageAdapter

后端 未结 5 1185
春和景丽
春和景丽 2021-02-04 15:05

I\'m designing an app that allows users to flip between multiple pages in a ViewPager. I\'ve been struggling trying to figure out how it is possible to remove a Fragment instan

相关标签:
5条回答
  • 2021-02-04 15:36

    Looking at the various documentation pieces, my best guess is that the views you are creating do not have an ID attached to them. Assuming that the fragment's saved state is created from Fragment.onSaveInstanceState, then the fragment will automatically save any view's state that has an id. You probably have a default id associated with your ListView/GridView if you created them from a layout file. You can also associate an id with the views by calling setId.

    Also, for your custom filled fragment, you may also have to do something custom in onSaveInstanceState.

    0 讨论(0)
  • 2021-02-04 15:44

    I also ran into this problem when I was using PagerSlidingTabStrip and using and instance of FragmentPagerAdapter, switching to FragmentStatePagerAdapter definitely worked.

    Then I use onSaveInstanceState() to save sate

    0 讨论(0)
  • 2021-02-04 15:51

    I had the same problem problem and solved it by implementing these two functions

        public void onSaveInstanceState (Bundle outState)
        public void onActivityCreated (Bundle savedInstanceState)
    

    on the fragments that I wanted to save. On the first function, you should save in the Bundle the date that you need to restore the views ( in my case I had a bunch of spinner so I used an int array to save their positions). The second function, which is called when restoring your fragment, is where you implement the restoring process.

    I hope this helps. I also made my adapter to inherit from FragmentStatePageAdapter but I am not sure that this is mandatory.

    0 讨论(0)
  • 2021-02-04 15:55

    Here's an example of how I implemented caching in PagerAdapter. After filling the cache all future view requests are served from cache, only data is replaced.

    public class TestPageAdapter extends PagerAdapter{
    
    private int MAX_SIZE = 3;
    private ArrayList<SoftReference<View>> pageCache = new ArrayList<SoftReference<View>>(3);
    
    
    public TestPageAdapter(Context context){
        // do some initialization
    }
    
    @Override
    public int getCount() {
        // number of pages
    }
    
    private void addToCache(View view){
        if (pageCache.size() < MAX_SIZE){
            pageCache.add(new SoftReference<View>(view));
        } else {
            for(int n = (pageCache.size()-1); n >= 0; n--) {
                SoftReference<View> cachedView = pageCache.get(n);
                if (cachedView.get() == null){
                    pageCache.set(n, new SoftReference<View>(view));
                    return;
                }
            }
        }
    }
    
    private View fetchFromCache(){
        for(int n = (pageCache.size()-1);  n>= 0; n--) {
            SoftReference<View> reference = pageCache.remove(n);
            View view = reference.get();
            if (view != null) {
                return view;
            }
        }
        return null;
    }
    
    @Override
    public Object instantiateItem(View collection, int position) {
        View view = fetchFromCache();
        if (view == null) {
            // not in cache, inflate manually
            LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.page, null);
        } 
        setData(view, position);
        ((ViewPager) collection).addView(view, 0);
        return view;         
    }
    
    private void setData(View view, int position){
        // set page data (images, text ....)
    }
    
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        currentItem = (View)object;
    }
    
    public View getCurrentItem() {
        return currentItem;
    }
    
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((View) object);
    }
    
    @Override
    public void destroyItem(View collection, int arg1, Object view) {
        ((ViewPager) collection).removeView((View) view);
        addToCache((View) view);
    }
    
    }
    
    0 讨论(0)
  • 2021-02-04 15:58

    Listing of main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TextView android:text="Page 1" android:id="@+id/textViewHeader"
            android:layout_width="fill_parent" android:layout_height="wrap_content"
            android:gravity="center" android:padding="10dip" android:textStyle="bold"></TextView>
        <android.support.v4.view.ViewPager
            android:layout_width="fill_parent" android:layout_height="fill_parent"
            android:id="@+id/viewPager" />
    </LinearLayout>
    

    Setting up the ViewPager

    ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
    MyPagerAdapter adapter = new MyPagerAdapter(this);
    viewPager.setAdapter(adapter);
    

    The PagerAdapter

    @Override
    public void destroyItem(View view, int arg1, Object object) {
             ((ViewPager) view).removeView((View)object);
    }
    @Override
    public int getCount() {
              return views.size();
    }
    @Override
    public Object instantiateItem(View view, int position) {
               View view = views.get(position);
               ((ViewPager) view).addView(view);
               return view;
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
               return view == object;
    }
    

    look here for more details view pager example

    0 讨论(0)
提交回复
热议问题