javaandroidandroid-studioandroid-studio-2.0tabbed-view

Getting currently selected tab of a tabbed activity


So I am currently developing an app which displays a json file via cards in the main activity. Depending on which tab is currently selected in my tabbed activity, a method which downloads the json file decides what json file to download (I pass an integer and there is a switch in the method).

Here is the method:

Fragment.Downloadjson(rootview,integer,context);

Now, for my tabbed Activity I have a SectionsPagerAdapter which has the usual stuff: getItem, getCount, and getPageTitle.

In getItem I am creating my new fragments:

    @Override
        public Fragment getItem(int position) {
            View v1 = getWindow().getDecorView().getRootView();
            switch (position) {
                case 0:
                    //Fragment.Download(v1,0,getApplicationContext());
                    return new Fragment().f(Fragment.page.TODAY);
                case 1:
                    //Fragment.Download(v1,1,getApplicationContext());
                    return new Fragment().f(Fragment.page.TOMORROW);
                default:
                    return new Fragment();
            }
        }

Exception :

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

I have found the source of this error to be the rootview parameter in my method, because it works in onCreateView with rootView as a parameter, because I define it there. Hovewer, I cannot make an if statement for the currently selected tab or currently displayed fragment there, because

a) I don't know how to get the currently selected tab

b) I'm not sure it would download the json file again after I switch the tab, because after all, the If statement would be in onCreateView

So, my question is,

how do I solve this?


Solution

  • Don't do it inside getItem() method. In getItem just create the fragment.

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new MyFragment0();
            case 1:
                return new MyFragment1();
            case 2:
                return new MyFragment2();
        }
        return null;
    }
    

    Override the method instantiateItem and in there keep a map of fragment and their position:

    private ArrayMap<Integer, MyFragmentBaseClass> mPagerFragmentMap = new ArrayMap<>();
    
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            MyFragmentBaseClass fragment = (MyFragmentBaseClass) super.instantiateItem(container, position);
            mPagerFragmentMap.put(position, fragment);
    
            return fragment;
        }
    

    note MyFragmentBaseClass can be a marker interface that all fragments implement.

    With the code above, you can already map each fragment to its tab.

    If you're using TabLayout you can now set a listener using setOnTabSelectedListener and use one of its methods onTabSelected to know when the user selects that tab and perform any operation you want.