A
A
Artem2012-12-25 14:54:21
Android
Artem, 2012-12-25 14:54:21

ViewPager with fragments, life cycles?

There is an application, in it ViewPager and two fragments. It is implemented like this:

public class MainActivity extends FragmentActivity {

    Vector<Fragment> fragments;
    ViewPager viewPager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        viewPager = (ViewPager) findViewById(R.id.pager);

        fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this, Fragment1.class.getName()));
        fragments.add(Fragment.instantiate(this, Fragment2.class.getName()));

        viewPager.setOffscreenPageLimit(fragments.size());
        PagerAdapter pagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);

        viewPager.setAdapter(pagerAdapter);

        viewPager.setCurrentItem(0);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode==1) {
            ((Fragment1)fragments.get(0)).load();
        }
    }

    class PagerAdapter extends FragmentPagerAdapter implements IconPagerAdapter {

        private List<Fragment> fragments;

        public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
        }

        @Override
        public Fragment getItem(int position) {
            return this.fragments.get(position);
        }

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

    }

}

In the Fragment1 class, I have variables that are declared as class properties and are initialized inside the onCreateView() method:
public class Fragment1 extends Fragment {

    ArrayList<ListItemObject> listItems = null;
    ArrayAdapter<ListItemObject> mAdapter;

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

        listItems = new ArrayList<ListItemObject>();
        mAdapter = new MyAdapter(getActivity(), listItems);
        listView.setAdapter(mAdapter);
    }

    void load() {
            mAdapter.clear();
            ...
    }

}

The problem is this. In fragments, sometimes (not too often) mAdapter is zero. That is, it turns out that the fragment is recreated, but without calling onCreateView(). I need it not to be recreated at all while the application is running. Also, getActivity() is used inside the fragment, which sometimes returns null. Perhaps these two problems are related. Is it possible to somehow fix this?

Answer the question

In order to leave comments, you need to log in

6 answer(s)
A
ara89, 2012-12-26
@ara89

Use the code from the sample in the docks . Don't store fragment references in the adapter.
To prevent the fragment from being recreated, you can call the setRetainInstance(true)
method. If you need to find a fragment by tag, then you can create it with your own tag using the FragmentTransaction class.
In the case of the ViewPager, the FragmentPagerAdapter assigns its own tags to the fragments, you can see this in its sources .
There, the makeFragmentName(int viewId, long id) method assigns view tags to fragments:

 private static String makeFragmentName(int viewId, long id) {
        return "android:switcher:" + viewId + ":" + id;
    }

where viewId is the id of the ViewPagera, id is the position of the fragment.
Accordingly, these tags can be used to take fragments from ViewPagera

R
recompileme, 2012-12-26
@recompileme

move adapter definition and activity to oncreate, not to oncreateview:
Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "init"); dlgs = new ArrayList<ClsVideos>(); adapter = new AdpVideos(getActivity(),dlgs); dlgsSize = 0; offset = 0; activity = getActivity(); }

R
recompileme, 2012-12-26
@recompileme

you can disable the re-creation of the fragment when changing the orientation of the activity: android:configChanges="keyboardHidden|orientation|screenSize"

A
Andrey M, 2014-05-26
@Collosteam

Try to use

PagerAdapter pagerAdapter = new PagerAdapter(getChildFragmentManager(), fragments);

instead of
PagerAdapter pagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);

A
Artem, 2012-12-26
@bartwell

That is, you can choose to either save the tags of the created fragments in MainActivity and do findFragmentByTag() in the adapter in getItem() , or in the same getItem() get fragments every time using Fragment.instantiate() and set setRetainInstance(true) for them )? I understand correctly? If so, what is the best way to do it?

D
dmitriy_deomin, 2015-06-08
@dmitriy_deomin

You can try changing the page limit
setOffscreenPageLimit
viewPager.setOffscreenPageLimit(5);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question