1

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

4444
  • 3,541
  • 10
  • 32
  • 43
Lotfi
  • 660
  • 1
  • 6
  • 21

2 Answers2

1

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).

Ravi Sisodia
  • 776
  • 1
  • 5
  • 20
  • who guarantee me that the fragment manager will not unload them from memory if it doesn't need them any more. They will not be recreated again, since the creation will be done only once in the MainActivity.onCreate – Lotfi Dec 29 '16 at 19:03
  • You've created them as a global variable, they will removed from memory with Activity only, else they will be in memory. – Ravi Sisodia Dec 30 '16 at 04:54
  • @ Ravi Sisodia, it was working until I put more than 3 Fragments (6 ones). Then, when swiping from the 4th to 3rd or 5th, the app crash – Lotfi Dec 31 '16 at 13:46
  • @ Ravi Sisodia perhaps it is related to 3 Fragments that are hold in the container only. So I upgraded to mViewPager.setOffscreenPageLimit(6); but no way it still crashes. Can I change the viewpager or SectionsPagerAdapter to oblige it to only hide/show and not remove (or dismiss) the fragment ? – Lotfi Dec 31 '16 at 13:49
  • I ended with creating all my fragments with new op. resultsfragment = new ResultsFragment(); and returning the pointer to the 6 fragments in the getItem. Works fine, until I tilted the screen, when the orientation changed, any swipe of the fingers to get the following fragments, crashes the application. Why ? – Lotfi Jan 07 '17 at 22:54
  • And What are the crash reports ? – Ravi Sisodia Jan 09 '17 at 05:20
0

@Lotfi you don't need to save your fragment inside activity, it is prone to leaks . Also you can assign id to each of your fragment and later when you need to reuse that fragment you can ask fragment manager to return the fragment by passing ie. by calling fragment manager method findFragmentByID() inside your getItem().

Alok
  • 881
  • 1
  • 11
  • 18
  • My fragment will handle a chart so I will waste too much to rec4eate it each time – Lotfi Dec 29 '16 at 16:51
  • You don't need to recreate it will just managed by fragment Manager just let it know what fragment you want to display,if it has already in stack then it will use same fragment. – Alok Dec 29 '16 at 17:41
  • Yes I know, but if it is not in the container anymore, it needs to recreate it and take time, see "Fragment Hiding vs Replace" in my first link "Creating-and-Using-Fragments" above. So I need to keep in memory and just swap between them – Lotfi Dec 29 '16 at 18:25
  • It will remain in memory but not attached to the container, so it will be reused without any issue. – Alok Dec 29 '16 at 18:52
  • Please consider this answer : http://stackoverflow.com/questions/13149446/android-fragments-when-to-use-hide-show-or-add-remove-replace/13185025#13185025 – Lotfi Dec 29 '16 at 21:43