Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewPager fragments recreation, are resumed but not visible

I have an issue with a ViewPager + FragmentPageAdapter.

Scenario: I have one Activity with inside a Fragment A. Fragment A has a ViewPager with Fragment B1 e Fragment B2. B1 e B2 are the same class, but different data as argument.

Problem: Everything works well at creation time. But when the app goes in background and the process is killed by android, trying to restore the last state, putting the app up again, Fragment B1 e B2 aren't visible in foreground, while Fragment A is. What seems a bit strange is that Fragment B1 e B2 are int the Fragment A's ChildFragmentManager and the are resumed because onStart() and onResume() are called (seen by Log). Moreover the pager is resumed with two pages, but empty or better with nothing visible.

If I understand well how FragmentPagerAdapter works, it should be its responsibility manage its own fragments and how they should be recreated. Moreover to enforce this point, FragmentPagerAdapter doesn't call getItem(int position) when come back from background if already exist a fragment in that position with a specified tag.

...so why I can't see Fragment B1 e B2, but just the Pager empty?

this is my sample code.

FragmentA

@Override
    public void onStart() {
        super.onStart();
        populateViewPager();
    }

    private void populateViewPager() {
        pager.setAdapter(new MyFragmentPageAdapter(getChildFragmentManager()));
        indicator.setViewPager(pager);
        indicator.notifyDataSetChanged();
    }

FragmentPagerAdapter

public class MyFragmentPageAdapter extends FragmentPagerAdapter {


    public MyFragmentPageAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return FragmentB.newInstance(position);
    }

    @Override
    public int getCount() {
        return 2; 
    }

    @Override
    public CharSequence getPageTitle(int position) {
        String title = "";
        if (position == 0)
            title = "Fragment B1";
        else if (position == 1)
            title = "Fragment B2";

        return title;
    }
}

Fragment B

        public static FragmentB newInstance(int position) {
                FragmentB f = new FragmentB();
                Bundle b = new Bundle();
                b.putInt(POSITION_IN_PAGER_ARGUMENT, position);
                f.setArguments(b);
                return f;
            }

            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                Log.d(TAG, "onCreate");
            }

            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                super.onCreateView(inflater, container, savedInstanceState);
                Log.d(TAG, "onCreateView");
                View root = inflater.inflate(R.layout.fragment_b_layout, container, false);

                empty = (TextView) root.findViewById(R.id.empty);
                list = (ListView) root.findViewById(R.id.list);

                return root;
            }

            @Override
            public void onStart() {
                super.onStart();
                Log.d(TAG, "onStart");
                populateListView(loadData());

            }

            @Override
            public void onStop() {
                super.onStop();
            }
    }
like image 608
Noodles Avatar asked May 14 '13 07:05

Noodles


1 Answers

use FragmentStatePagerAdapter instead of FragmentPagerAdapter. It worked for me. But there will be memory issues (only while screen orientation change) if your ViewPager has lots of views to display.

like image 195
user2886615 Avatar answered Oct 19 '22 09:10

user2886615