DMCApps / NavigationFragment

The purpose of this manager is to work with the ViewPager, Tabs and Navigation drawer to handle a single stack flow of fragments on the screen. It makes use of a main Fragment as a container and presents and hides fragments within it as children.
MIT License
28 stars 8 forks source link

access the top level or any level of navigation remotely #5

Closed jjhesk closed 8 years ago

jjhesk commented 8 years ago

Thank you so much on your amazing code! Now I have an real world situation to deal with and I cant get to anywhere for this problem. Please let me know if i have explain it correctly. There is the main activity. this activity has one Framelayout and it initialized a navigation fragment (A) by using SingleStackNavigationManagerFragment. In the (A) I got it initialized a viewpager which carries 3 navigationfragments B, C, and D. There is a button E attached in the B.

What is the solution for me to click on button E and it navigate to a new navigation fragment on the (A) navigation level? assume i can use another method to call the superLevelPresent but I have no tag or nothing to indicator which one is the parent. I am sure there are alot of conflicts over the back buttons and other things. i start thinking if that is the case, would it better to add configuration policy for the SingleStackNavigationManagerFragment to receive events or clicks coming from the child navigation fragment or just fragment. I think this is far important to configure out before implement other small features. A huge thank you to your amazing work.

DMCApps commented 8 years ago

Hey jj,

I don't have time tonight to put together an example. If I'm understanding your situation

you have the following hierarchy

                          Main Activity 
                      SingleStackManager (A)
                       ViewPagerFragment
Frag B                        Frag C                           Frag D
Button E (click should present on A)

If this is correct, assuming your ViewPagerFragment is an instance of NavigationFragment (which it much be in order to adhear to the present/dismiss methods of the SingleStackManager), I'm thinking that you can attach the parent SingleStackNavigationManagerFragment to each of the Fragments B/C/D if they are NavigationFragment (or NavigationListFragment). There is an exposed method in the NavigationFragments for setting the NavigationManager via setNavigationManager(NavigationManager navManager). So in your adapter you can do the following within the ViewPagerAdapter

       // In your ViewPagerAdapter's getItem Method.
       @Override
        public Fragment getItem(int position) {
            // Initialize your fragment B/C/D
            NavigationFragment navFrag = FragB.newInstance();
            // Assuming the ViewPagerFragment is a NavigationFragment it should have access to it's parent NavigationManager through the getNavigationManager() method
            navFrag.setNavigationManager(getNavigationManager());
            // Show the NavigationFragment in the ViewPager.
            return navFrag;
        }

Now that you have set the children to use the ViewPagerFragment NavigationManager you can present/dismiss as you would before in those Fragments

Please let me know if this is helpful!

jjhesk commented 8 years ago

Let me try with this method and I let u know. Thanks for the big help. Would you adding one more fragment in the viewpager under the Tab Example in your sample code for the above demonstration please?

jjhesk commented 8 years ago

Now I am working with to integrate with the library smarttablayout and I found a solution to extend from the fragmentitemdapter.


package com.hkm.layout.patchSmartLayoutItem;

import android.support.v4.app.FragmentManager;
import android.view.ViewGroup;

import com.dmcapps.navigationfragment.fragments.NavigationFragment;
import com.dmcapps.navigationfragment.manager.NavigationManagerFragment;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;

/**
 * Created by hesk on 25/2/16.
 */
public class FragmentPagerItemAdapter extends com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter {

    private final NavigationManagerFragment nmf;

    public FragmentPagerItemAdapter(FragmentManager fm, NavigationManagerFragment navh, FragmentPagerItems pages) {
        super(fm, pages);
        nmf = navh;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Object item = super.instantiateItem(container, position);
        if (item instanceof NavigationFragment) {
            NavigationFragment nav = (NavigationFragment) item;
            nav.setNavigationManager(nmf);
        }
        return item;
    }
}

and in the setup code I had to adding additional manager to bypass the original fragment manager.


    public FragmentPagerItemAdapter getAdapter() {
        final FragmentPagerItems.Creator itemCreator = FragmentPagerItems.with(getActivity());
        try {
            final Config overhead_data = ConfigurationSync.getInstance().getFoundation().data;
            tab_list.clear();
            if (overhead_data.navigation.size() > 0) {
                final Iterator<NavigationItem> nk = overhead_data.navigation.iterator();
                while (nk.hasNext()) {
                    final NavigationItem g = nk.next();
                    if (g.name.equalsIgnoreCase("Featured")) {
                        itemCreator.add(tB.home.getStringId(), tB.home.getClazz());
                    } else {
                        itemCreator.add(
                                g.name,
                                template_product_display.class,
                                template_product_display.con_general(g.link)
                        );
                        //   itemCreator.add(g.name, testpage.class);
                        tab_list.add(g.link);
                    }
                }
            }
        } catch (Exception e) {
        }
        FragmentPagerItems all_pagers = itemCreator.create();
        Iterator<FragmentPagerItem> it = all_pagers.iterator();

        return new FragmentPagerItemAdapter(getChildFragmentManager(), getNavigationManager(), itemCreator.create());
    }
DMCApps commented 8 years ago

Please note this is already in the current release version.

I have set up an example for this in the project. Please take a look at the example project in the develop branch https://github.com/DMCApps/NavigationFragment/tree/develop/app/src/main/java/com/dmcapps/navigationfragmentexample/GitIssue5Example

In the example there are 2 non NavigationFragment as the first and last tab. The 2nd tab is the NavigationFragment. You can see in the example that the NavigationFragment after create but BEFORE returning in the Adapter we call:

// Get the NavigationManager of the current frament (The ViewPagerFragment) and assign it as the NavigationManager of the child of the ViewPager.
navFragment.setNavigationManager(getNavigationManager())

This then sets the navigation manager of this fragment to the navigation manager of the ViewPagerFragment

jjhesk commented 8 years ago

@DMCApps is this on the version 0.1.2? It is now i cannot use go back button as it will crash immediately.

baconlmy48yhesk02262016112421

This is the exactly the same bug but it happens constantly once i press the back button to the previous navigation fragment. Both the same if I am using viewpageradapter or just a singlestackfragmentmanager.

DMCApps commented 8 years ago

Functionality for setNavigationManager has always been there since the start. It is one of the key methods that allows me to set the manager on each NavigationFragment when being presented so that you can call present/dismiss without worrying about the internal details.

As for this bug, I'm not able to reproduce on any of my samples. Even the sample that you recently merged into my branch is working fine on a device using Genymotion running 5.0.0 and 6.0.0. Can you give me maybe the specific device and android version you are running. Could it be related to that?

jjhesk commented 8 years ago

currently i am running on OnePlusOne android 5.1.1 stock

DMCApps commented 8 years ago

As of version 0.2.0.2 there is no need to call setNavigationManager(). The manager is now smart enough to look at the getParentFragment() and continue up the stack of parents until it finds a NavigationFragmentManager. It then returns that to use for any methods.