Al Lelopath
Al Lelopath

Reputation: 6778

Get fragment activity outside of Fragment.OnCreateView()

I have a Fragment with a TableLayout. The data in the table is from a SQLite db. The SQLite db is populated from a RESTful webservice in an AsyncTask in the MainActivity. The Fragment must wait for the task to complete before populating the table. The Fragment listens for the task onPostExecute() method to be called. When it is, the method onLoadAndStoreComplete in the Fragment is called. This all works.

What doesn't work is that I need the fragment activity in order to create new TableRows and TextViews in onLoadAndStoreComplete and I can't get it.

I've tried:
- making a class member fragmentActivity and assigning in onCreateView(), but by the time it gets to onLoadAndStoreComplete(), it is null.
- calling this.getActivity() again in onLoadAndStoreComplete(), but it returns null.

How do I get the fragment activity?

MyFragment.java:

public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
        fragmentActivity = this.getActivity(); // return value is valid
        ...
}

@Override                               
public void onLoadAndStoreComplete() {  

        fragmentActivity = this.getActivity(); // returns null
    ...
}

from MainActivity.java (extends ActionBarActivity)

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainActivity = this;
        setContentView(R.layout.activity_main);

        Resources resources = getResources();
        String[] tabTitleArray = { resources.getString(R.string.first_fragment),  
                                   resources.getString(R.string.second_fragment),  
                                   resources.getString(R.string.help_fragment) };

        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getSupportActionBar();
        mAdapter = new TabsPagerAdapter(this.getSupportFragmentManager());

        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);        

        for (String tab_name : tabTitleArray) {
            actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
        }

        // On swiping the ViewPager, select the respective tab 
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position) ;// on changing the page, make respected tab selected
            }
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }
            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });

        String url = "http://myrestfulwebservice";
        Fragment secondFragment = mAdapter.getItem(SECOND_TAB);
            new LoadAndStoreDataTask((OnLoadAndStoreCompleteListener)secondFragment).execute(url);    
    }

} // end OnCreate

TabsPagerAdapter.java

public class TabsPagerAdapter extends FragmentPagerAdapter {

    public TabsPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int index) {
        switch (index) {
        case 0:
            return new FirstFragment();
        case 1:
            return new SecondFragment();
        case 2:
            return new HelpFragment();
        }

        return null;
    }

    @Override
    public int getCount() {
        return 3; // get item count - equal to number of tabs
    }

    public static void setTabColor(TabHost tabhost) {
        for(int i=0;i<tabhost.getTabWidget().getChildCount();i++) {
            tabhost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#FF0000")); //unselected
        }
        tabhost.getTabWidget().getChildAt(tabhost.getCurrentTab()).setBackgroundColor(Color.parseColor("#0000FF")); // selected
    }

}

Upvotes: 2

Views: 2089

Answers (2)

Daniel Nugent
Daniel Nugent

Reputation: 43322

I haven't tested this, but it seems to me that it would work.

Add a Context parameter to the constructor for both TabsPagerAdapter and MyFragment.

Something like this:

TabsPagerAdapter.java:

public class TabsPagerAdapter extends FragmentPagerAdapter {

    private Context mCtx;

    public TabsPagerAdapter(FragmentManager fragmentManager, Context context) {
        super(fragmentManager);
        mCtx = context;
    }

    @Override
    public Fragment getItem(int index) {
        switch (index) {
        case 0:
            return new FirstFragment(mCtx);
        case 1:
            return new SecondFragment(mCtx);
        case 2:
            return new HelpFragment(mCtx);
        }

        return null;
    }

    @Override
    public int getCount() {
        return 3; // get item count - equal to number of tabs
    }

    public static void setTabColor(TabHost tabhost) {
        for(int i=0;i<tabhost.getTabWidget().getChildCount();i++) {
            tabhost.getTabWidget().getChildAt(i).setBackgroundColor(Color.parseColor("#FF0000")); //unselected
        }
        tabhost.getTabWidget().getChildAt(tabhost.getCurrentTab()).setBackgroundColor(Color.parseColor("#0000FF")); // selected
    }

}

MainActivity.java:

  mAdapter = new TabsPagerAdapter(this.getSupportFragmentManager(), this);

MyFragment.java (do this in FirstFragment, SecondFragment, and HelpFragment):

public static class MyFragment extends Fragment {

    private Context fragmentActivity ;

    public MyFragment(Context context){
        fragmentActivity  = context;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //.........            
        return rootView;
    }

    @Override
    public void onLoadAndStoreComplete() {

        //do something with fragmentActivity

    }
}

Upvotes: 2

yummy
yummy

Reputation: 580

It seems the AsyncTask starts too early. suggest loading the db in onActivityCreated(), it's be called after onCreateView

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    //load your db here
}

Upvotes: 1

Related Questions