0

I have an Activity which uses a ViewPager to create three Fragments in the ViewPager class I set the Fragments to setRetainInstace(true); when they are created.

Inside one of my Fragments I am displaying some editable info. This Fragment launches a DialogFragment to edit the info.

When the user doesn't change orientation I am able to Update the Info and send the results back to the Fragment in View, however, once I change the Orientation, and make an Update to the Info my Interface which is attached in the DialogFragments onAttach() method i am getting a NullPointerException.

I don't understand why though because, each time the new DialogFragment is launched the onAttach() Method is always called.

How should I solve this? Can I save the state of the Interface ? and if so How?

Here is my DialogFragment Code: The GenericDialogFragment Class is only used to make changes to the Appearance

public class Fragment1 extends GenericDialogFragment implements WebServiceResult{



// -------------------------------------------------------------------------
// Member Variables
//--------------------------------------------------------------------------
//Webservice Callback
private WSRequest mActiveRequest = null;
// The Current Context of the Application
private Context mClassContext = null;
// Interface reference for communication
private static CommunicateResults communicateResults = null;


// -------------------------------------------------------------------------
// New Instance Method
//--------------------------------------------------------------------------    

public static Fragment1 newInstance(int userId, GenericObject [] objects, GenericGroup [] groups, Object currentObject){
    // Initialize a new Fragment1
    Fragment1 fragment = new Fragment1();
    // Create a new Bundle
    Bundle args = new Bundle();

    fragment.setArguments(args);

    // Return the Fragment1
    return fragment;
}

// -------------------------------------------------------------------------
// Class Functions / Methods
//--------------------------------------------------------------------------    

// States that the Interface is attached to the parent activity
@Override public void onAttach(Activity activity)
{
    // Perform the Default Behavior
    super.onAttach(activity);
    Log.d("ONAttach()","On attach() is called" );
    // Try 
    try{
        // Attach the interface to the activity
        communicateResults = (CommunicateResults) ((MainActivity)  getActivity()).findFragment(EditableFragment1.class);

    }catch(Exception ex){
        // Print the stack trace
        ex.printStackTrace();
    }
}

// States that the Dialog's View has been Created
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    // Return the Inflated XML Layout
    return inflater.inflate(R.layout.fragment1, container, false);
}

// States that the fragment has been created, last chance to update the UI
@Override
public void onActivityCreated(Bundle savedInstanceState){
    // Perform the Default behavior
    super.onActivityCreated(savedInstanceState); 

    mClassContext = getActivity();

    // Get the Arguments passed into the Fragment instance
    savedStateData = getArguments();

    // Reference all the UI Elements in the View    


    // Add listeners to the Button Widgets


    // If the savedInstanceState is not null, get the current object
    if(savedStateData != null){

        // Get the object out of the state data
        mCurrentObject = savedStateData.getParcelable(STATE_DATA_CURRENT_OBJECT);

    }



}


//-----------------------------------------------------------------------------
// Webservice Callback methods
//-----------------------------------------------------------------------------

// States that the web service has succeeded 
@Override public void webserviceSucceeded(WebServiceBase finishedService, Object responseData) 
{

    Log.d("EDIT Object", responseData.toString());

    if(responseData != null){

        if(mDeletingObject){



            // Send Back to the object to remove
            communicateResults.sendBackData(mCurrentObject, ACTION_DELETE);

        }else{

            JSONObject tempObject = (JSONObject) responseData;

            try{

                // Parse Data ...



            }catch(Exception ex){

                ex.printStackTrace();
                // TODO: The Object was deleted from the Lest
            }

            // If we are creating a object, bundle the information to pass to the parent activity
            if(mCreatingObject){

                // Create a new Workout Object
                mCurrentObject = new Object();


                // Callback to Parent Activity to notify that data has changed
                communicateResults.sendBackData(mCurrentObject, ACTION_CREATE);

                // Else the Object was updated
            }else{
                // Create a new  Object
                mCurrentObject = new Object();


                // Callback to Parent Activity to notify that data has changed
                communicateResults.sendBackData(mCurrentObject, ACTION_UPDATE);
            }
        }


    }

    // Dismiss the fragment


}


// States that the web service has failed
@Override
public void webserviceFailed(WebServiceBase finishedService,
        Object errorData) {


    // Display the Error
    displayErrorData(errorData);

}

}

kandroidj
  • 13,784
  • 5
  • 64
  • 76
  • It sounds like your Activity is you interface, if you're using onAttach(Activity activity);, so why not just use (CastToInterface)getActivty();? – Submersed Jan 16 '14 at 16:05
  • My Activity is not my interface. The interface is declared inside my Fragment with editable data. So Im creating an interface in this fragment, and then i am implementing it in the DialogFragment. I tried to make this change and i get ClassCastException because this tries to cast the interface to my Activity where its not implemented – kandroidj Jan 16 '14 at 16:11
  • Gotcha. Can you post your fragment code? – Submersed Jan 16 '14 at 16:13
  • Added my DialogFragment if you want to see where im attaching the interface. @Submersed – kandroidj Jan 16 '14 at 16:55
  • Is this a nested fragment? In that case use getParentFragment() to get a reference to the parent fragment. – Bartek Filipowicz Jan 16 '14 at 22:26
  • Its a DialogFragment Communicating back to a Fragment in And activity with a view pager. The issue is I am losing my Fragment reference when the orientation changes. When i first call instantiate on the fragmentdialog i have no problems. its the second call after orientation change. that give me a null pointer to the current Fragment – kandroidj Jan 16 '14 at 22:29

1 Answers1

0

I think you're looking for onActivityCreated(Bundle bundle);, this is the Fragment equivalent of the Activity class's onRestoreSavedInstanceState(Bundle bundle);.

From the documentation:

public void onActivityCreated (Bundle savedInstanceState) Added in API level 11

Called when the fragment's activity has been created and this fragment's view hierarchy instantiated. It can be used to do final initialization once these pieces are in place, such as retrieving views or restoring state. It is also useful for fragments that use setRetainInstance(boolean) to retain their instance, as this callback tells the fragment when it is fully associated with the new activity instance. This is called after onCreateView(LayoutInflater, ViewGroup, Bundle) and before onViewStateRestored(Bundle). Parameters savedInstanceState If the fragment is being re-created from a previous saved state, this is the state.

When your fragment is destroyed on an orientation change, save its state as name value pairs in the Activity's Bundle, then when it needs to be recreated, instantiate a new Interface in this method, and set the respective fields/retrieve the parcelable in your new Fragment instance.

Submersed
  • 8,810
  • 2
  • 30
  • 38
  • A little confused here. Shouldn't this not matter if the onAttach() method is called everytime a new DialogFragment is created? or is this a problem in my Fragment that implements the interface? – kandroidj Jan 16 '14 at 16:26
  • Not sure, I'd have to see how you've implemented your fragment. – Submersed Jan 16 '14 at 16:31
  • Theres a ton of code in the fragment I will try to pair it down so I only share what you need. – kandroidj Jan 16 '14 at 16:33
  • Okay so even after onAttach() is called i log the interface and its null when the orientation changes. And when i log the Activity it is not null. So i think its the Fragment Class is null when the orientation changes – kandroidj Jan 16 '14 at 16:35
  • Not really enough to go off of, would just be guesses. If you can post your stack trace and activity I'll check back later. – Submersed Jan 16 '14 at 17:15
  • Yeah, so i found the problem by checking my Fragment1 Reference in onAttach() after the Orientation changes the Fragment1 is null. but the View still shows. So it is something with the Way my ViewPager is returning the Fragment Reference. Thanks for your help for now. I will see if i can handle the reference better. – kandroidj Jan 16 '14 at 17:24