Search code examples
androidandroid-fragmentsandroid-viewpagerfragmenttransaction

Persistant fragments and viewpager


I want to use 3 fragments within an Android App, I red: Creating-and-Using-Fragments .But I want to use the viewpager for swiping and displaying the fragments like explained in: ViewPager-with-FragmentPagerAdapter .But this code or the default code of Android Studio Example, use newInstance to create the instances, each time it is needed and destroy when not needed.

// Returns the fragment to display for that page
    @Override
    public Fragment getItem(int position) {
        switch (position) {
        case 0: // Fragment # 0 - This will show FirstFragment
            return FirstFragment.newInstance(0, "Page # 1");
        case 1: // Fragment # 0 - This will show FirstFragment different title
            return FirstFragment.newInstance(1, "Page # 2");
        case 2: // Fragment # 1 - This will show SecondFragment
            return SecondFragment.newInstance(2, "Page # 3");
        default:
            return null;
        }
    }

but I want to create once for all :

        // Within an activity

private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        fragmentA = FragmentA.newInstance("foo");
        fragmentB = FragmentB.newInstance("bar");
        fragmentC = FragmentC.newInstance("baz");
    }
}

and only hide/show them, as in the example:

    // ...onCreate stays the same

// Replace the switch method
protected void displayFragmentA() {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    if (fragmentA.isAdded()) { // if the fragment is already in container
        ft.show(fragmentA);
    } else { // fragment needs to be added to frame container
        ft.add(R.id.flContainer, fragmentA, "A");
    }
    // Hide fragment B
    if (fragmentB.isAdded()) { ft.hide(fragmentB); }
    // Hide fragment C
    if (fragmentC.isAdded()) { ft.hide(fragmentC); }
    // Commit changes
    ft.commit();
}

But how to do that with a FragmentPagerAdapter public Fragment getItem(int position) no longer has to be like that

Also, how to access a data

 public double [][] tableaux;

that is in the MainActivity from one Fragment. Data will be persistant if I assign a pointer of the Fragment I just created in the MainActivity onCreate to point on the MainActivity.tableaux


Solution

  • You can return you pre-initialized fragments in getItem method.

    @Override
    public Fragment getItem(int position) {
        switch (position) {
        case 0: return fragmentA;
        case 1: return fragmentB;
        case 2: return fragmentC;
        default: return null;
    }
    

    UPDATE: @Alok is right. You should not have fragment references in Activity. And I suggest instead of increasing offscreen page limit using setOffscreenPageLimit, you should consider saving & restoring fragment states using public void onSaveInstanceState(Bundle) and savedInstanceState argument of public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState).