2

I have an implementation of fragment as explained here. I have expanded the BaseFragment class to handle navigation icon onClickListener. The code for that looks like this,

private void onBackButtonPressed(int tag)
    {
        switch (tag)
        {
            case Global.DISPLAY_STORE:
            {
                setTitle("Loyalty Cards",Color.BLACK);
                setToolBar(getResources().getColor(R.color.white), Global.ADD_CARD,R.drawable.add_round_btn);
                break;

            }
            case Global.ADD_CARD:
            {
                setTitle("Wallet", Color.WHITE);
                setToolBar(getResources().getColor(R.color.colorPrimary), Global.DISPLAY_STORE,R.drawable.icon_shopping);
                getFragmentManager().popBackStack();
                break;
            }
            case Global.CARD_DETAILS:
            {
                setTitle("Loyalty Cards",Color.BLACK);
                setToolBar(getResources().getColor(R.color.white), Global.ADD_CARD,R.drawable.add_round_btn);
                getFragmentManager().popBackStack();
                break;
            }
        }

    }

I am using this block of code to change the ToolBar icons and colors when back button is pressed.This code resides in BaseFragment.

Here is how I implement the code to handle back press,

I have my fragment extending the BaseFragment

public class CardDetailsFragment extends BaseFragment

Now inside the BaseFragment onCreate I have this code,

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

        mainActivity = (MainActivity) getActivity();

        ImageButton righBarButton = (ImageButton) mainActivity.getToolbar().findViewById(R.id.btn_ToolBarRightBtn);
        righBarButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onRighBarButtonClicked(Integer.parseInt(v.getTag().toString()));
            }
        });

        mainActivity.getToolbar().setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackButtonPressed(BACK_BUTTON_TAG);
            }
        });

        getFragmentManager().addOnBackStackChangedListener(this);

        shouldDisplayHomeUp();
    }

By this every fragments back button press and the right bar button item click in toolbar are handled.

Consider the scenario I have three fragments A , B and C.

From Fragment A I open Fragment B and Then Fragment C. Now From fragment C I click the back button to reach fragment B. The back button event is handled by above code and it works fine.

Now from Fragment B, I click the back button to reach Fragment A. But when I click back button I am getting exception

java.lang.IllegalStateException: Fragment CardDetailsFragment{d8b35b5} not attached to Activity
                                                                                    at android.support.v4.app.Fragment.getResources(Fragment.java:636)

here the CardDetailsFragment is the FragmentC, but I am clicking the back button from Fragment B

Zach
  • 9,989
  • 19
  • 70
  • 107

1 Answers1

1

The first time the user presses the back button, Fragment C is no longer necessary and thus it is detached from the activity. The problem lies in the fact that even though Fragment C is detached, it is still registered as a listener for back stack change events.

The second time the user presses the back button, your onBackStackPressed() method is called in Fragment C. When getResources() is executed, there is no activity attachment so getResources() fails.

Something like this in your fragment should fix it:

     @Override
     public void onDestroy() {
         getFragmentManager().removeOnBackStackChangedListener(this);
         super.onDestroy();
     }
kris larson
  • 30,387
  • 5
  • 62
  • 74