Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

commit fragment from onLoadFinished within activity

I have an activity which loads a data list from the server using loader callbacks. I have to list out the data into a fragment which extends

SherlockListFragment 

i tried to commit the fragment using

Fragment newFragment   = CategoryFragment.newInstance(mStackLevel,categoryList);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.simple_fragment, newFragment).commit();

in onLoadFinished and it gives an IllegalStateException saying

java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished

I have referred the example in actionbar sherlock, but those examples have loaders within the fragments and not the activity.

Can anybody help me with this o that I can fix it without calling the loader from the fragment!

like image 650
Aswathy P Krishnan Avatar asked Sep 05 '12 07:09

Aswathy P Krishnan


People also ask

How do you associate a fragment with an activity?

Add a fragment to an activity You can add your fragment to the activity's view hierarchy either by defining the fragment in your activity's layout file or by defining a fragment container in your activity's layout file and then programmatically adding the fragment from within your activity.

Can a fragment without a layout can be attached to an activity?

A fragment is not required to be a part of the Activity layout ; you may also use a fragment without its own UI as an invisible worker for the Activity but it needs to be attached to an Activity in order to appear on the screen. Save this answer.

Can fragments be used in multiple activities?

You can use multiple instances of the same fragment class within the same activity, in multiple activities, or even as a child of another fragment. With this in mind, you should only provide a fragment with the logic necessary to manage its own UI.

Is fragment destroyed when activity is destroyed?

As Fragment is embedded inside an Activity, it will be killed when Activity is killed.


2 Answers

Atlast, I have found a solution to this problem. Create a handle setting an empty message and call that handler onLoadFinished(). The code is similar to this.

@Override
public void onLoadFinished(Loader<List<Station>> arg0, List<Station> arg1) {
    // do other actions
    handler.sendEmptyMessage(2);
}

In the handler,

private Handler handler = new Handler()  { // handler for commiting fragment after data is loaded
    @Override
    public void handleMessage(Message msg) {
        if(msg.what == 2) {
            Log.d(TAG, "onload finished : handler called. setting the fragment.");
            // commit the fragment
        }
    }
}; 

The number of fragments depend on the requirement.

This method can be mainly used in case of stackFragments, where all fragments have different related functions.
like image 60
Aswathy P Krishnan Avatar answered Nov 10 '22 23:11

Aswathy P Krishnan


As per the Android docs on the onLoadFinished() method:

Note that normally an application is not allowed to commit fragment transactions while in this call, since it can happen after an activity's state is saved. See FragmentManager.openTransaction() for further discussion on this.

https://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoadFinished(android.content.Loader, D)

(Note: copy/paste that link into your browser... StackOverflow is not handling it well..)

So you simply should never load a fragment in that state. If you really don't want to put the Loader in the Fragment, then you need to initialize the fragment in your onCreate() method of the Activity, and then when onLoadFinished occurs, simply call a method on your fragment.

Some rough pseudo code follows:

public class DummyFragment {

     public void setData(Object someObject) {
           //do stuff
     }

public class DummyActivity extends LoaderCallbacks<Object> {

     public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);

           Fragment newFragment = DummyFragment.newInstance();
           FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
           ft.add(R.id.simple_fragment, newFragment).commit();

           getSupportLoaderManager.initLoader(0, null, this)
     }

     // put your other LoaderCallbacks here... onCreateLoader() and onLoaderReset()

     public void onLoadFinished(Loader<Object> loader, Object result) {
           Fragment f = getSupportLoaderManager.findFragmentById(R.id.simple_fragment);
           f.setData(result);
     } 

Obviously, you'd want to use the right object.. and the right loader, and probably define a useful setData() method to update your fragment. But hopefully this will point you in the right direction.

like image 41
kwazi Avatar answered Nov 10 '22 23:11

kwazi