Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is fragment finally attached to activity?

I have a main fragment with a viewpager inside it. This viewpager has 2 pages (list fragments). When I start the activty, the main fragment is shown and I also show the first paged fragment. This paged fragment displays data from a db using AsyncTask.

In the main fragment I have:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    onPageSelected(0);
}

@Override
public void onPageSelected(int position) {
    Fragment fragment = (Fragment) pagerAdapter.instantiateItem(viewPager, position);
    if (fragment instanceof IPagedFragment) {
        ((IPagedFragment) fragment).onShown(getActivity());
    }
}

And the interface is:

public interface IPagedFragment {
    void onShown(FragmentActivity activity);
}

The first issue I have is that I have to pass the activity as a parameter because when onShown gets called, the activity is still null.

Furthermore, the paged fragments use progressbar logic similar to the LoginActivity sample. I also get the following exception:

IllegalStateException: Fragment PagedFragment1{4201f758} not attached to Activity at android.support.v4.app.Fragment.getResources(Fragment.java:620)

So what is the correct stage to start retrieving data from db once the paged fragment is fully available to the UI?

like image 959
Ivan-Mark Debono Avatar asked Jul 20 '15 08:07

Ivan-Mark Debono


1 Answers

Issues like yours is the reason some developers are starting to question if fragments are really that good or useful.

Also "the correct" is debatable as you can do it in a variety of places and different developers will give you different answers, But let me try to supply you some useful info.

The attach/detach callbacks:

public void onAttach(Activity activity);
public void onDetach();

between those two methods any call to getActivity() will return the non-null activity the fragments is connected to. You can override them and use a private boolean isAttached to keep track of that call.

Also useful is the:

public void onActivityCreated (Bundle savedInstanceState)

this method is called AFTER the Activity.onCreate method. That is very important if you rely on some initialisation that happened there.

Also it's important to remember that on the moment the fragment transaction happens, the Fragment.onCreate happens after the Activity.onCreate and during rotation it happens before it.

As a general rule of thumb I use the Fragment.onStart() / Fragment.onStop() for getting/listening to data. On those calls, all the UI have been created, the fragment is attached to the activity and those callbacks don't get called if there's a dialog/popup (pause/resume does)

like image 86
Budius Avatar answered Sep 27 '22 17:09

Budius