0

I have a navigation drawer that transitions between several activities. In each activity I have one base fragment that might launch other fragments. I want the navigation drawer toggle icon to show when I am in the base fragment but when I add another fragment I need to show the back arrow.

I have been following the example laid out by riwnodennyk at: Switching between Android Navigation Drawer image and Up caret when using fragments

But it is not working for me. The arrow does show up but I am unable to click it. When clicking on it nothing happens.

OptionsMenuListner in non-base fragment:

    @Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Get item selected and deal with it
    Log.d("HERE", "HERHEHREHREHddddddREe");


    return false;
}

I do call setHasOptionsMenu(true); in the fragment.

the relevant parts of the navigation fragment:

 public void setup(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
    mFragmentContainerView = getActivity().findViewById(fragmentId);
    mDrawerLayout = drawerLayout;


    mActionBarDrawerToggle = new ActionBarDrawerToggle(getActivity(), mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
            setActionBarArrowDependingOnFragmentsBackStack();

            if (!isAdded()) return;
            getActivity().invalidateOptionsMenu();

            if (mCallbacks != null && nextSelectedPosition != mCurrentSelectedPosition) {
                mCurrentSelectedPosition = nextSelectedPosition;
                mCallbacks.onNavigationDrawerItemSelected(nextSelectedPosition);
            }
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            setDrawerIndicatorEnabled(true);
            if (!isAdded()) return;

            getActivity().invalidateOptionsMenu();
        }
    };

    mActionBarDrawerToggle.setHomeAsUpIndicator(R.drawable.appbar_back);


    mDrawerLayout.post(new Runnable() {
        @Override
        public void run() {
            mActionBarDrawerToggle.syncState();
        }
    });

    mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);
    ((BaseNavigationActivity)getActivity()).getSupportFragmentManager().addOnBackStackChangedListener(mOnBackStackChangedListener);
}

private FragmentManager.OnBackStackChangedListener
        mOnBackStackChangedListener = new FragmentManager.OnBackStackChangedListener() {
    @Override
    public void onBackStackChanged() {
        Log.d("TAG", "Back stack was called");
        setActionBarArrowDependingOnFragmentsBackStack();
    }
};

private void setActionBarArrowDependingOnFragmentsBackStack() {
    int backStackEntryCount =
            ((BaseNavigationActivity)getActivity()).getSupportFragmentManager().getBackStackEntryCount();
    Log.d("TEST", "Back Stack Count: " + backStackEntryCount);
    mActionBarDrawerToggle.setDrawerIndicatorEnabled(backStackEntryCount == 0);
}
Community
  • 1
  • 1
Nath5
  • 1,665
  • 5
  • 28
  • 46

2 Answers2

1

The Following method works for me.

private boolean mToolBarNavigationListenerIsRegistered = false;

public void enableButton(boolean enable) {
    if (enable) {
        mDrawableToggle.setDrawerIndicatorEnabled(false);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        if (!mToolBarNavigationListenerIsRegistered) {
            mDrawableToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onBackPressed();
                }
            });

            mToolBarNavigationListenerIsRegistered = true;
        }

    } else {
        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
        mDrawableToggle.setDrawerIndicatorEnabled(true);
        mDrawableToggle.setToolbarNavigationClickListener(null);
        mToolBarNavigationListenerIsRegistered = false;
    }
}here

At the time of calling this method if you pass the true as a parameter it will show a Back Arrow and worked as a Back Press and by passing false in it will show Navigation Drawer Icon and open Navigation Drawer.

Android Dev
  • 1,496
  • 1
  • 13
  • 25
0

I encountered the same problem. I am no sure, why we don't receive a call in onOptionsItemSelected, but i created a workaround.

I modfied the drawer layout. You now can add a listener, that will notfiy you everytime the toggle button is pressed.

You can prevent the toggle button from its action, or let it continue.

Here's the class: ListenableDrawerLayout.java

public class ListenableDrawerLayout extends DrawerLayout {

private OnToggleButtonClickedListener mOnToggleButtonClickedListener;
private boolean mManualCall;

public ListenableDrawerLayout(Context context) {
    super(context);
}

public ListenableDrawerLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public ListenableDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

/**
 * Sets the listener for the toggle button
 *
 * @param mOnToggleButtonClickedListener
 */
public void setOnToggleButtonClickedListener(OnToggleButtonClickedListener mOnToggleButtonClickedListener) {
    this.mOnToggleButtonClickedListener = mOnToggleButtonClickedListener;
}

/**
 * Opens the navigation drawer manually from code<br>
 * <b>NOTE: </b>Use this function instead of the normal openDrawer method
 *
 * @param drawerView
 */
public void openDrawerManual(View drawerView) {
    mManualCall = true;
    openDrawer(drawerView);
}

/**
 * Closes the navigation drawer manually from code<br>
 * <b>NOTE: </b>Use this function instead of the normal closeDrawer method
 *
 * @param drawerView
 */
public void closeDrawerManual(View drawerView) {
    mManualCall = true;
    closeDrawer(drawerView);
}


@Override
public void openDrawer(View drawerView) {

    // Check for listener and for not manual open
    if (!mManualCall && mOnToggleButtonClickedListener != null) {

        // Notify the listener and behave on its reaction
        if (mOnToggleButtonClickedListener.toggleOpenDrawer()) {
            return;
        }

    }
    // Manual call done
    mManualCall = false;

    // Let the drawer layout to its stuff
    super.openDrawer(drawerView);
}

@Override
public void closeDrawer(View drawerView) {

    // Check for listener and for not manual close
    if (!mManualCall && mOnToggleButtonClickedListener != null) {

        // Notify the listener and behave on its reaction
        if (mOnToggleButtonClickedListener.toggleCloseDrawer()) {
            return;
        }

    }
    // Manual call done
    mManualCall = false;

    // Let the drawer layout to its stuff
    super.closeDrawer(drawerView);
}

/**
 * Interface for toggle button callbacks
 */
public static interface OnToggleButtonClickedListener {

    /**
     * The ActionBarDrawerToggle has been pressed in order to open the drawer
     *
     * @return true if we want to consume the event, false if we want the normal behaviour
     */
    public boolean toggleOpenDrawer();

    /**
     * The ActionBarDrawerToggle has been pressed in order to close the drawer
     *
     * @return true if we want to consume the event, false if we want the normal behaviour
     */
    public boolean toggleCloseDrawer();
}

}

Lets look at the usage:

 mDrawerLayout.setOnToggleButtonClickedListener(new ListenableDrawerLayout.OnToggleButtonClickedListener() {
        @Override
        public boolean toggleOpenDrawer() {

            // Check if we want to navigate back
            if (...want back...) {
                // -> Do back navigation
                getActivity().onBackPressed();
                // return true to prevent drawer from opening                    
                return true;
            }

            return false;
        }

        @Override
        public boolean toggleCloseDrawer() {
            // Return always false to allow closing everytime
            return false;
        }
    });

IMPORTANT: If you do a manual open/close from your code, use the new methods openDrawerManual and closeDrawerManual

Adrian
  • 75
  • 4