0

I have a MainActivity with two fragments. Fragment 1 is MapsFragment and fragment 2 is ListFragment. When I start the app I get the user location (lat and lon) from Fragment 1. What I also want to do is pass that data to Fragment 2, before it starts loading, before onCreateView is called in Fragment 2, so I can do stuff with lat and lon I receive from Fragment 1.

Usually I would send data from fragment to fragment using intent and sending it through activity, but my question is a bit more specific, because fragment 2 is loaded right after fragment 1, before I get the time to pass the data.

Some of the stuff I have tried includes: this, this, this, this, this, this, this,this

My MainActivity:

tabLayout = findViewById(R.id.sliding_tabs);
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_one)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.tab_two)));

tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);

viewPager = findViewById(R.id.viewpager);
adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.setOffscreenPageLimit(2);

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition());
        // Step 2 - undo expand for collapsible toolbar
        appBarLayout.setExpanded(true);

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
}

My PagerAdapter:

public class PagerAdapter extends FragmentStatePagerAdapter {
    private int mNumOfTabs;

    public PagerAdapter(FragmentManager fm, int NumOfTabs) {
        super(fm);
        this.mNumOfTabs = NumOfTabs;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                return new MapsFragment();
            case 1:
                return new ListFragment();
            case 2:
                return null;
        }
    }

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

Now, this is how I pass lat and lon to MainActivity, after I get it in my MapsFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
    Intent intent = new Intent(getActivity().getBaseContext(), 
    MainActivity.class);
    intent.putExtra("latitude", latitude);
    intent.putExtra("longitude", longitude);
    getActivity().startActivity(intent);
...
}

Solution:
It is based on both answers and the comment. In my list fragment I called method only if lat and lon are not empty. And after I get lat and lon it is called again, I was using interface and a listener.

Better solution would be to rewrite my code and write it properly, as suggested in the comments.

Banana
  • 2,435
  • 7
  • 34
  • 60
  • Can I ask why you are using a PagerAdapter if the fragment isn't meant to be interacted with until fragment 1 is loaded? Is it not a possibility to read map data from base activity and commit the fragment2 when you have the data available and you/user wants to see the data? – Ezzy Jun 22 '18 at 09:47
  • @Ezzy When I first started working on this I did not plan this communication, so I used pager adapter... Unfortunately, if I were to change it I would have to make quite a few changes now, so I am looking for a way to avoid this if at all possible. – Banana Jun 22 '18 at 09:51
  • 1
    sounds to me like it would be better to make it properly instead of finding ways around it. You might run into problems later which could have been avoided if you just re-wrote it. – Ezzy Jun 22 '18 at 09:53
  • @Ezzy I am kinda aware of that :( just thought to give it a shot and find an easier way, but if I do not find it by tonight I will probably rewrite my code over the weekend :) – Banana Jun 22 '18 at 09:58

2 Answers2

1

Create an interface which your activity will implement, call that interface from your MapsFragment once you get the values Longitude and Latitude. On the ListFragment use the method setUserVisibleHint. There get the value from the activity.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
     ////Use the longitude and latitude values. 
    }
Ravi Rawal
  • 233
  • 3
  • 14
  • Try creating a method in the activity say getData() then call the method from the setUserVisibleHint method like ((MyActivity) getActivity()).getData(); – Ravi Rawal Jun 22 '18 at 13:28
  • Yes, I did try to do that. The issue I am facing is that I cannot get that data to my second activity before it starts loading. I will give it a go again tonight. – Banana Jun 22 '18 at 14:18
1

The best way is to get common data inside Activity which is used by both fragments and then add fragments.

Anyways for your problem i have two solutions in my mind.

1- Load data in Fragment 2 only when Fragment 2 is visible to the user. For this purpose you can override this method inside Fragment 2.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
         //load data here
    }  
}

2- Initially fill Fragment 2 with some dummy data (or leave empty) and update data in Fragment 2 whenever Fragment 1 finishes loading data by sending broadcast event from Fragment 1 to Fragment 2.