4

How to create a new ViewPager everytime I remove the fragment(create it again)? My pager is surviving the fragment destruction.

I have a ViewPager inside a Fragment, but when I remove the fragment from the FrameLayout where it is and the add it back. His ViewPager is the same of the old fragment instance(I do think it is) but all of the fragments are gone( empty pager is empty :( ). How can I recreate the ViewPager again?

This code is on my onCreateView() method on my fragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View fragment = inflater.inflate(getLayoutID(), container,false);
    ViewPager pager = (ViewPager) fragment.findViewById(R.id.myPager);

    PagerAdapter newAdapter = new MyPagerAdapter(getFragmentManager(), getFragments());
    pager.setAdapter(newAdapter);

    return fragment;
}

And I think that's all you guys need to know.

adheus
  • 3,985
  • 2
  • 20
  • 33
  • what "view" exactly are you calling findViewById on? There is no such variable in the local scope – Timo Ohr Jun 12 '12 at 20:29
  • sorry, man. just fixed it. it was fragment. – adheus Jun 12 '12 at 20:44
  • how do you conclude that is the same pager? Inflating a layout should create all new view objects – Timo Ohr Jun 12 '12 at 21:09
  • You are using fragments inside of fragments. This is not supported. Please either move the `ViewPager` out of the fragment, or do not use a fragment-based `PagerAdapter`. – CommonsWare Jun 12 '12 at 21:26
  • Because it when create the fragment again, the pager return with no fragments in it. no fragments are displayed. and it is created in the same way on both times. – adheus Jun 12 '12 at 21:35
  • @CommonsWare do you know any examples that I can use an PagerAdapter without using fragments? Like ImageView instead? – adheus Jun 12 '12 at 21:46
  • I have not seen such an example. I had planned on creating one myself, but have not gotten around to it yet. – CommonsWare Jun 12 '12 at 22:13
  • I will create one and post here. – adheus Jun 13 '12 at 01:39

1 Answers1

2

Now knowing I can't have fragments inside fragments, I did this ViewPagerAdapter with an array of view that you can pass(could be anything you want) and show with it. Here comes the code:

ViewPagerAdapter

import java.util.List;

import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;

public class ViewPagerAdapter extends PagerAdapter{

    private List<View> pages;

    public ViewPagerAdapter(List<View> pages) {
        this.pages = pages;
    }



    @Override  
    public Object instantiateItem(View collection, int position) {  
        ((ViewPager) collection).addView(pages.get(position),0);  

        return pages.get(position);  
    }  

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

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    /**  
     * Remove a page for the given position. The adapter is responsible  
     * for removing the view from its container, although it only must ensure  
     * this is done by the time it returns from {@link #finishUpdate()}.  
     *  
     * @param container The containing View from which the page will be removed.  
     * @param position The page position to be removed.  
     * @param object The same object that was returned by  
     * {@link #instantiateItem(View, int)}.  
     */  
    @Override  
    public void destroyItem(View collection, int position, Object view) {  
        ((ViewPager) collection).removeView((View) view);  
    }  

    @Override  
    public boolean isViewFromObject(View view, Object object) {  
        return view==((View)object);  
    }  

    /**  
     * Called when the a change in the shown pages has been completed. At this  
     * point you must ensure that all of the pages have actually been added or  
     * removed from the container as appropriate.  
     * @param container The containing View which is displaying this adapter's  
     * page views.  
     */  
    @Override  
    public void finishUpdate(View arg0) {}  

    @Override  
    public void restoreState(Parcelable arg0, ClassLoader arg1) {}  

    @Override  
    public Parcelable saveState() {  
        return null;  
    }  

    @Override  
    public void startUpdate(View arg0) {}  
}  

And here comes an extra abstract fragment where you could just override the abstract methods and voila:

AbstractPagerFragment

import java.util.List;

import templateDigital.util.ViewPagerAdapter;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public abstract class AbstractPagerFragment extends Fragment {

    private ViewPager pager;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        View fragment = inflater.inflate(getLayoutID(), container,false);
        setRetainInstance(false);
        PagerAdapter mPagerAdapter = new ViewPagerAdapter(getViews());
        pager = (ViewPager) fragment.findViewById(getPagerID());
        pager.setAdapter(mPagerAdapter);
        pager.getAdapter().notifyDataSetChanged();

        return fragment;
    }


    public abstract List<View> getViews();

    public abstract int getLayoutID();

    public abstract int getPagerID();

    @Override
    public void onDestroy() {
        super.onDestroy();
        pager = null;
        System.gc();
    }


}
adheus
  • 3,985
  • 2
  • 20
  • 33