带后箭头的Android导航抽屉

时间:2015-03-03 23:26:00

标签: android android-actionbar navigation-drawer back-stack android-toolbar

我有一个导航抽屉,可在多个活动之间切换。在每个活动中,我有一个可能启动其他片段的基本片段。我希望导航抽屉切换图标显示我在基本片段中的时间,但是当我添加另一个片段时,我需要显示后退箭头。

我一直在关注riwnodennyk列出的例子: Switching between Android Navigation Drawer image and Up caret when using fragments

但它不适合我。箭头确实显示但我无法点击它。点击它没有任何反应。

非基本片段中的OptionsMenuListner:

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


    return false;
}

我调用setHasOptionsMenu(true);在片段中。

导航片段的相关部分:

 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);
}

2 个答案:

答案 0 :(得分:1)

以下方法适用于我。

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

在调用此方法时,如果您将true作为参数传递,它将显示一个后退箭头并作为Back Press工作,并在其中传递false将显示导航抽屉图标并打开导航抽屉。

答案 1 :(得分:0)

我遇到了同样的问题。 我不确定,为什么我们没有收到onOptionsItemSelected的电话,但我创建了一个解决方法。

我修改了抽屉布局。您现在可以添加一个监听器,每次按下切换按钮时都不会使用该监听器。

您可以阻止切换按钮的操作,或让它继续。

这是班级: 的 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();
}

}

让我们看一下用法:

 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;
        }
    });

重要提示:如果您从代码中手动打开/关闭,请使用新方法 openDrawerManual和closeDrawerManual