Flo June
Flo June

Reputation: 13

Why is my Fragment not instantiated ? Activity to Fragments communication

i am trying to send data from my Activity(which gets Data from Firebase) to another Fragments. It works only if i change data on the Firebase but not on his first attempt while the Activity gets created. On the first attempt the fragments in the Methods passDataToInfoFragment and passDataToRanklistFragment are always NULL. I have no clue why, so i need ur help.

GroupDetailFragmentCommunication:

public interface GroupDetailFragmentCommunication {
    public void passDataToInfoFragment(PublicGroup group);
    public void passDataToRanklistFragment(PublicGroup group);
}

GroupDetailActivity:

public class GroupDetailActivity extends AppCompatActivity implements GroupDetailFragmentCommunication{

    private FirebaseAuth auth;
    private FirebaseDatabase database;
    private DatabaseReference reference;
    private GroupDetailPagerAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_group_detail);
        this.initFirebase();
        this.setUpToolbar();
        this.setUpTabLayout();
        this.getPublicGroup();
    }

    public void initFirebase() {
        auth = FirebaseAuth.getInstance();
        database = FirebaseDatabase.getInstance();
        reference = database.getReference();
    }

    public void setUpToolbar() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setTitle("Details");
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    public void setUpTabLayout() {
        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        ArrayList<String> tabs = new ArrayList<>();
        tabs.add("Info");
        tabs.add("Rank");

        final ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
        this.adapter = new GroupDetailPagerAdapter(getSupportFragmentManager(), tabs);
        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);
    }

    public void getPublicGroup() {
            reference.child("groups").child("public").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                PublicGroup pg = snapshot.getValue(PublicGroup.class);
                if (pg != null) {
                    pg.setKey(snapshot.getKey());
                    passDataToInfoFragment(pg);
                    passDataToRanklistFragment(pg);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
            
            }
        });
    }


     @Override
    public void passDataToInfoFragment(PublicGroup group) {
        InfoFragment fragment = (InfoFragment) this.adapter.getFragment(0);
        if (fragment != null) {
            fragment.fragmentCommunication(group);
        } else {
            Log.i("Bla", "Fragment 1 is not instantiated");
        }
    }
s
    @Override
    public void passDataToRanklistFragment(PublicGroup group) {
        RanklistFragment fragment = (RanklistFragment) this.adapter.getFragment(1);
        if (fragment != null) {
            fragment.fragmentCommunication(group);
        } else {
            Log.i("Bla", "Fragment 2 is not instantiated");
        }
    }


}

GroupDetailPagerAdapter:

public class GroupDetailPagerAdapter extends FragmentStatePagerAdapter {
    private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
    private ArrayList<String> tabHeader;

    public GroupDetailPagerAdapter(FragmentManager fm, ArrayList<String> tabHeader) {
        super(fm);
        this.tabHeader = tabHeader;
    }

    @Override
    public Fragment getItem(int position) {

        switch (position) {
            case 0:
                Fragment infoTab = new InfoFragment();
                return infoTab;
            case 1:
                Fragment ranklistTab = new RanklistFragment();
                return ranklistTab;
            default:
                return null;
        }
    }

    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    public Fragment getFragment(int position) {
        return registeredFragments.get(position);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabHeader.get(position);
    }
}

Upvotes: 1

Views: 811

Answers (2)

Gober
Gober

Reputation: 3662

To get a fragment instance from your adapter, call instantiateItem instead of getFragment (in your passData... methods).

If you call instantiateItem, you get the fragment that the adapter is referencing. Don't worry about calling instantiateItem multiple times, if it is already instantiated you just get a reference back.

Do not maintain your own references to fragments in the adapter, as these can be swapped out by your adapter without these references being updated.

Upvotes: 0

AZOM
AZOM

Reputation: 265

After a quick glance at your code I have some suspicions:

  • Have you tried setting a breakpoint getPublicGroup() -> onDataChange(DataSnapshot snapshot) method? If pg is null there your "passing"-methods will not be called.

If this is not the case, it might be the case that your fragments are not fully instantiated when you call the this.getPublicGroup() in the onCreate() of the the parent activity.

  • You can try to move this line to the onResume() method of your parent activity instead, does this help?

Upvotes: 1

Related Questions