1

Here is what I'm trying to do

I have an inner class which extends a FragmentPagerAdapter, but I don't want to do a network call for each Fragment. So I'm trying to do just one call and send the result I get from it to each Fragment to be dealt by each one of them according to their needs.

But here lies my problem

It seems that for some reason the fragments are loaded before the network call returns a successful result and I was wondering how do I avoid that to happen?

Thanks so really very much for any possible help on that!!

public class WelcomeActivity extends FragmentActivity {

    private List<Reward> mTutorialList = new ArrayList<>();
    private String myResult = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);

        ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
        pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));

    }

    private class MyPagerAdapter extends FragmentPagerAdapter {

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

        }

        private void getData() {

            JsonObject jo = new JsonObject();

            String user_id = LocalSave.getUserId();

            jo.addProperty("user_id", user_id);
            jo.addProperty("tag", "all");
            jo.addProperty("limit", "-1");


            RewardsAPI.postData(jo, new RewardsAPI.ThisCallback() {
                @Override
                public void onSuccess(Rewards rewards) {
                    Log.d(App.TAG, "onSuccess");

                    myResult = rewards.getRewards().get(0).getRedeemUrl();
                    mTutorialList = rewards.getRewards();
                }

                @Override
                public void onFailure() {
                    Log.e(App.TAG, "onFailure");
                }

                @Override
                public void onError(APIError error) {
                    Log.e(App.TAG, "Exception: " + error.getErrorMessage());
                }
            });

        }


        @Override
        public Fragment getItem(int pos) {

            getData();

            switch (pos) {

                case 0:
//                    return WelcomeFragment.newInstance(mTutorialList.get(0));
                    return GetStartedFragment.newInstance("Get Started!");
                case 1:
                    return FitnessPlanFragment.newInstance("fitness plan");
                case 2:
                    return NutritionPlanFragment.newInstance("nutrition plan");
                default:
                    return GetStartedFragment.newInstance("Get Started!");
            }
        }

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

    }

}
Francislainy Campos
  • 3,462
  • 4
  • 33
  • 81
  • I believe you'll have to give us a little more info on that matter. Like, when are you making the network call? And it seems that are some methods missing on the adapter. It's hard to read it that way and find what's wrong. – Mauker Oct 14 '17 at 15:51
  • Hi @mauker Thanks very much for your help on that. I'm afraid that's the whole code I have for that file. Don't have anything else for the adapter and was trying to call my getData method within the getItem to try to make them load before the fragments are displayed but that's what seems not to be working as expected at the moment. – Francislainy Campos Oct 14 '17 at 15:55
  • I believe I found the problem. Writing the answer now. – Mauker Oct 14 '17 at 15:56
  • See if the answer helps. – Mauker Oct 14 '17 at 19:21
  • It worked! Yeeeaaahhh! Thanks so really very much @Mauker!! I have no words to express my appreciation for your help on this problem! Thanks so so much! :) – Francislainy Campos Oct 14 '17 at 19:59
  • You're very welcome! :D Glad to help – Mauker Oct 15 '17 at 03:48

1 Answers1

1

You problem lies on both your getItem() and getCount() methods.

You said you want to display the Fragments only when the network call has executed. So you can't tell beforehand that your adapter have 3 items, and neither can you instantiate them on the getItem() method.

From the FragmentPagerAdapter docs:

Fragment getItem (int position)

Return the Fragment associated with a specified position.

And also from the docs:

int getCount()

Return the number of views available.

So, what you're telling the adapter is: "I already have three items, and as soon as you're set, instantiate them on the provided positions".

My suggestion is for you to either create an addFragments(ArrayList<Fragment> fragments) method, and call it once your network stuff is done, or do the networking outside the adapter, and only then you'll create the adapter itself.

Check this related question for further reading. And this tutorial.

Community
  • 1
  • 1
Mauker
  • 11,237
  • 7
  • 58
  • 76