Reputation: 6778
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
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
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