0

I'm sorry, I'm sure that this will be simple but I just cannot see where I'm going wrong here.

I've got a Fragment (a tool list) that can start a number of other fragments (tools) in a two pane set up. There is an activity that sits above & I am using it to manage the removal of tool fragments when their 'close button' is pressed. It then pops a tool from the backstack if one exists.

The strange thing is, that I have this working within one fragment but the 'cut & pasted' code into another fragment doesn't work & throws a NPE. Any ideas why much appreciated.

The Activity snippet:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;    

public class MyActivity extends FragmentActivity implements OnFragmentButtonClickedListener {

private final static int CLOSE_BUTTON = 0;
...


public void onFragmentButtonClicked(int button, Fragment fragId) {
    Log.i(TAG, "onFragmentButton");
    // process closing of fragment
    if (button == CLOSE_BUTTON) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.remove(fragId);
        ft.commit();
    }
    // then restore most recent fragment from backstack
    if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        getSupportFragmentManager().popBackStack();
    }
}
}

This fragment works:

import android.support.v4.app.Fragment;

public class FirstFragment extends Fragment implements OnClickListener{

OnFragmentButtonClickedListener fragmentButtonListener;
private final static int CLOSE_BUTTON = 0;


// empty constructor
public FirstFragment() {};

// Activity must implement this interface
public interface OnFragmentButtonClickedListener {
    public void onFragmentButtonClicked (int button, Fragment fragId);
}

@Override
public void onAttach(Activity activity) {
    Log.i(TAG, "onAttach");
    super.onAttach(activity);
    try {
        fragmentButtonListener = (OnFragmentButtonClickedListener) activity;
    } catch (ClassCastException e) {
        Log.w(TAG, (activity.toString() + " must implement OnFragmentButtonClickedListener"));
    }
}

...

public void onClick(View v) {
    Log.i(TAG, "onClick");
    switch (v.getId()) {
    case R.id.btn_st_close:
        //close activity
        eraseData(prefs);
        Log.i(TAG, "Frag Id = " + String.valueOf(getFragmentManager().findFragmentById(getId())));
        fragmentButtonListener.onFragmentButtonClicked(CLOSE_BUTTON, getFragmentManager().findFragmentById(getId()));
        break;
    }
}

But, this one throws a NPE in the onClick method when calling the onFragmentButtonClicked() method on the fragmentButtonListener.

import android.support.v4.app.Fragment;

public class SecondFragment extends Fragment implements OnClickListener {

OnFragmentButtonClickedListener fragmentButtonListener;
private final static int CLOSE_BUTTON = 0;

// empty constructor
public SecondFragment() {};

// Activity must implement this interface
public interface OnFragmentButtonClickedListener {
    public void onFragmentButtonClicked (int button, Fragment fragId);
}

@Override
public void onAttach(Activity activity) {
    Log.i(TAG, "onAttach");
    super.onAttach(activity);
    try {
        fragmentButtonListener = (OnFragmentButtonClickedListener) activity;
    } catch (ClassCastException e) {
        Log.w(TAG, (activity.toString() + " must implement OnFragmentButtonClickedListener"));
    }
}

...

 public void onClick(View v) {
     Log.i(TAG, "OnClick");
    switch (v.getId()) {
    case R.id.btn_wc_close:
        //close activity
        eraseData(prefs);
        Log.i(TAG, "Frag Id = " + String.valueOf(getFragmentManager().findFragmentById(getId())));
        try {
            fragmentButtonListener.onFragmentButtonClicked(CLOSE_BUTTON, getFragmentManager().findFragmentById(getId()));
        }
        catch (Exception e) {
            Log.i(TAG, "Exception: " + e);
        }
        break;
        }
    }

From logcat, I can see that the fragment Id is not null so I'm very confused.

08-20 09:13:49.096: I/Second Fragment(1691): onCreate
08-20 09:13:49.096: I/Second Fragment(1691): Frag Id = SecondFragment{41355d68 #1 id=0x7f090093}
08-20 09:13:49.106: I/Second Fragment(1691): onCreateView
08-20 09:13:49.406: I/Second Fragment(1691): onActivityCreated
08-20 09:13:49.560: I/Second Fragment(1691): onClick
0 09:13:51.766: I/Second Fragment(1691): Frag Id = SecondFragment{41355d68 #1 id=0x7f090093}
08-20 09:13:51.766: W/dalvikvm(1691): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
08-20 09:13:51.826: E/AndroidRuntime(1691): FATAL EXCEPTION: main
08-20 09:13:51.826: E/AndroidRuntime(1691): java.lang.NullPointerException
08-20 09:13:51.826: E/AndroidRuntime(1691):     at SecondFragment.onClick(IceTurbFragment.java:136)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at android.view.View.performClick(View.java:4084)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at android.view.View$PerformClick.run(View.java:16966)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at android.os.Handler.handleCallback(Handler.java:615)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at android.os.Handler.dispatchMessage(Handler.java:92)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at android.os.Looper.loop(Looper.java:137)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at android.app.ActivityThread.main(ActivityThread.java:4745)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at java.lang.reflect.Method.invokeNative(Native Method)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at java.lang.reflect.Method.invoke(Method.java:511)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-20 09:13:51.826: E/AndroidRuntime(1691):     at dalvik.system.NativeStart.main(Native Method)

Thanks for any help.

Dan Hunn
  • 15
  • 3
  • 5
  • Could you please point out which line is IceTurbFragment line 136. I think your view passed to OnClick might be null – Mike T Aug 20 '12 at 09:37
  • Hi @Mike, I de-identified the code but it was the line inside the try braces of the onClick method. The view were not null as onClick was being called but the correct answer was as accepted below. Thanks for looking though. – Dan Hunn Aug 20 '12 at 13:15

1 Answers1

1

I can see you define 2 interface with the same name in each fragment.

public interface OnFragmentButtonClickedListener {
     public void onFragmentButtonClicked (int button, Fragment fragId);
}

But the activity can implement only one interface with this name (in this case, I believe your activity implement interface of first fragment) and maybe this cause error null pointer exception of second fragment.

//where is OnFragmentButtonClickedListener come from?
public class MyActivity extends FragmentActivity implements FirstFragment OnFragmentButtonClickedListener 

Try to write OnFragmentButtonClickedListener outside of 2 fragments ( maybe in another file)

ductran
  • 10,043
  • 19
  • 82
  • 165
  • 1
    Brilliant, thanks for that @R4j. Because I have learned Java/Android organically, it's always these silly mistakes that get me bogged down. – Dan Hunn Aug 20 '12 at 11:13
  • I think you could also just implement FirstFragment.OnFragmentButtonClickedListener, SecondFragment.OnFragmentButtonClickedListener separately. – Steffen Jan 09 '15 at 09:10