Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid recreate Fragment into ViewPager?

I am using a ViewPager with a FragmentStatePagerAdapter that contains 5 pages.

In the first page I have a ListView with items. When I change at the last page of the ViewPager, and I come back to first page, my ListView is empty because the Adapter has been recreated.

Android always calls to the next methods: onAttach(), onCreate(), onCreateView(), onViewCreated(), onActivityCreated(), onStart() and onResume().

I would like don't use ViewPager.setOffscreenPageLimit() methods to avoid that my pages can be destroyed. There are any alternative solution?

The behavior I want is the same that makes Facebook.

What I doing wrong? How I can keep the data in my ListView?

Code of my FragmentStatePageAdapter:

public class AdapterMain extends FragmentStatePagerAdapter {
    List<ChicfyFragment> fragments = new ArrayList<ChicfyFragment>();

    public AdapterMain(FragmentManager fm) {
        super(fm);

        fragments.add(new FragmentShop());
        fragments.add(new FragmentSearch());
        fragments.add(new FragmentSell());
        fragments.add(new FragmentNotification());
        fragments.add(new FragmentProfile());
    }

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

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

Code of the first page of my ViewPager:

public class FragmentShop extends ChicfyFragment implements SwipeRefreshLayout.OnRefreshListener {

    ListView mListView;
    AdapterProductList mAdapter;
    SwipeRefreshLayout mSwipeRefreshLayout;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_main_shop, container, false);

        mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh);
        mListView = (ListView) view.findViewById(R.id.fragment_main_shop_listview);

        return view;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // setup adapter
        mAdapter = new AdapterProductList((FragmentActivity) getActivity(), new ArrayList());

        // setup listview
        mListView.setAdapter(mAdapter);
        mListView.setDivider(null);

        // setup swipe
        mSwipeRefreshLayout.setColorScheme(R.color.red, R.color.white, R.color.blue, R.color.white);
        mSwipeRefreshLayout.setOnRefreshListener(this);
    }

    @Override
    public void onRefresh() {
        new AsyncTask<Void, Void, Void>() {
            List<String> list = new ArrayList<String>();

            @Override
            protected Void doInBackground(Void... voids) {
                try {
                    Thread.sleep(1000);
                    for(int i=0; i<10; i++) list.add("" + i);
                } catch (Exception e) {}
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);

                mAdapter.clear();
                mAdapter.addAll(list);
                mAdapter.notifyDataSetChanged();

                mSwipeRefreshLayout.setRefreshing(false);
            }
        }.execute();
    }
}
like image 229
cpalosrejano Avatar asked Oct 08 '14 12:10

cpalosrejano


People also ask

Can I use ViewPager with views not with fragments?

yes...you can use View instead of Fragment in viewpager. Here you can Find Whole example that will help you to achieve Viewpager without Fragment. Go through this documentation. Save this answer.

Should I use ViewPager or ViewPager2?

ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .

Is ViewPager deprecated?

This method may be called by the ViewPager to obtain a title string to describe the specified page. This method is deprecated. This method should be called by the application if the data backing this adapter has changed and associated views should update.


2 Answers

You can use this line for X count of fragments

mViewPager.setOffscreenPageLimit(X);

like image 153
Amr Barakat Avatar answered Sep 17 '22 14:09

Amr Barakat


I have fixed it as follow:

In the method onViewCreated() of my Fragment, I avoid recreate the Adapter, checking if is null.

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // setup adapter
    if(mAdapter == null) {
        mAdapter = new AdapterProductList((FragmentActivity) getActivity(), new ArrayList());
        mAdapter.setOnLastItemListener(this);
    }

    ...
    ...

}
like image 44
cpalosrejano Avatar answered Sep 17 '22 14:09

cpalosrejano