0

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?

Vikrant Kashyap
  • 6,398
  • 3
  • 32
  • 52
just_deko
  • 1,024
  • 1
  • 14
  • 29
  • check this link for getting current tab http://stackoverflow.com/questions/3583405/get-index-of-selected-tab-in-tabhost – Brahmam Yamani Apr 05 '16 at 17:16
  • @BrahmamYamani I don't have a tabactivity, I use the preconstructed _tabbed activity_ from android studio. Therefor, I can't use Tabhost. – just_deko Apr 05 '16 at 17:43

1 Answers1

1

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.

Aitor Viana
  • 933
  • 6
  • 15
  • And if I don't have a Tablayout? – just_deko Apr 05 '16 at 20:12
  • 1
    It depends. What are you using to implement the tabs? The only thing you need is being able to detect the tab selection. – Aitor Viana Apr 06 '16 at 09:39
  • The deprecated Tablistener and all the deprecated tab methods (When you create a new activity, there is a "tabbed activity" preset, that's what I use). Since this instantiateitem returns the current fragment I would need some kind of method which does something when I change the tab. How do I do that? – just_deko Apr 06 '16 at 13:15
  • 1
    My Android Studio creates a "tabbed activity" using a view pager (same as I assumed before). I've never used `TabListener`, do you refer to `ActionBar.TablListener` ? If so it has methods for `onTabSelected` (see http://developer.android.com/reference/android/app/ActionBar.TabListener.html) – Aitor Viana Apr 06 '16 at 13:25
  • One last question: If I want to use my method `Fragment.Downloadjson(rootview,integer,context);` in onTabSelected, how could i pass the rootview to the method? – just_deko Apr 06 '16 at 15:22
  • 1
    If `onTabSelected` method is inside the class that has the `rootview` just make it a class field so that you can get access to it. – Aitor Viana Apr 06 '16 at 16:29
  • and if it doesn't? my rootview is in `onCreateView`, and `onTabSelected` just stands by itself in the activity class. Getting the rootview to other methods was also a problem for me, because none of the [contemporary methods](http://stackoverflow.com/questions/5488509/any-easy-generic-way-in-android-to-get-the-root-view-of-a-layout) work for me. I think it is because `onTabSelected` gets called before the actual view is created. – just_deko Apr 08 '16 at 15:39
  • 1
    can you post some code? I didn't understand where is what :D – Aitor Viana Apr 08 '16 at 15:46
  • 1
    The private `mPagerFragmentMap` should be a field of your `MainActivity`. Every fragment should keep a copy of the rootView as fragment field. You could implement a getter method `getRootView`. Lastly, in `onTabSelected` just get the fragment rootview using `mPagerFragmentMap.get(tab.getPosition()).getRootView()` and use it at will. – Aitor Viana Apr 09 '16 at 14:12