工具栏 setNavigationOnClickListener 中断 ActionbarDrawerToggle 功能

Tool bar setNavigationOnClickListener breaks ActionbarDrawerToggle functionality

我正在将操作栏换成工具栏,而且我几乎已经准备好了所有拼图。我的问题特别是如果我导航 'up' 并恢复导航抽屉,抽屉切换按钮不再有效。我发现如果我将抽屉模式设置为解锁我可以滑动打开抽屉,但不能点击打开抽屉。

所以我加载片段 A,抽屉行为正常,向下转到片段 B 并应用向上图标,向上点击返回 A,抽屉将不再通过点击打开。

进入片段B:

Toolbar t = mHostingActivity.getToolbar();
        mHostingActivity.getDrawerToggle().setDrawerIndicatorEnabled(false);
        mHostingActivity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        t.setNavigationIcon(mHostingActivity.getV7DrawerToggleDelegate().getThemeUpIndicator());
        t.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popBackStackToTop(mHostingActivity);
            }
        });

/**
 * Pop the back stack and hide the Up caret all the way to the top level of the {@link com.loylap.activities.MainActivity}
 *
 * @param activity our hosting activity
 */
public static void popBackStackToTop(MainActivity activity) {
    if (activity != null) {
        FragmentManager fm = activity.getSupportFragmentManager();
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        activity.getDrawerLayout().setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        activity.getDrawerToggle().setDrawerIndicatorEnabled(true);
    }
}

导航抽屉的设置就像示例一样,也许问题是设置选项的旧方法?例如,我的 activity:

中仍然有这个
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

编辑:

好的,我已将问题缩小到 setNavigationOnClickListener()。如果我不设置它(并通过后退按钮向上) - 抽屉行为正确。所以现在的问题是我如何正确地允许用户去 'up',并在我们上去之后恢复点击侦听器?

我认为你不能使用:

     t.setNavigationIcon(mHostingActivity.getV7DrawerToggleDelegate().getThemeUpIndicator());
     t.setNavigationOnClickListener(new View.OnClickListener() ...

因为它会破坏您正常的导航抽屉行为。

而是在 onCreateOptionsMenu(Menu menu, MenuInflater inflater) 中尝试这样的事情:

mHostingActivity.getDrawerToggle().setDrawerIndicatorEnabled(false);
mHostingActivity.getDrawerToggle().setHomeAsUpIndicator(mHostingActivity.getV7DrawerToggleDelegate().getThemeUpIndicator());

然后在 onOptionsItemSelected

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:  
        popBackStackToTop(mHostingActivity);
        return true;

    default:
        break;
    }
    return false;
}

PS:不要忘记使用 setHasOptionsMenu(true);在您的 onCreateView 片段中。

所以我发现我创建了错误的点击侦听器。我需要 setToolbarNavigationClickListener() :)

而不是 setNavigationOnClickListener()

一个微妙但重要的变化,现在工具栏与 v7 ActionBarDrawerToggle 协同工作

/**
 * Create the Up caret for a lower level fragment {@link com.loylap.activities.MainActivity}
 *
 * @param activity our hosting activity
 */
public static void createUpButton(final MainActivity activity)
{
    ActionBarDrawerToggle toggle = activity.getDrawerToggle();
    //Disables onClick toggle listener (onClick)
    toggle.setDrawerIndicatorEnabled(false);
    toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            popBackStackToTop(activity);
        }
    });

    Toolbar t = activity.getToolbar();
    t.setNavigationIcon(activity.getV7DrawerToggleDelegate().getThemeUpIndicator());
    activity.getDrawerLayout().setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}

受到 Daniel Wilson 解决方案的启发,但您只需要做一次,一切就绪。

在我的 NavigationDrawersetUp() 中(或者您可以在初始化 ActionBarDrawerToggle 实例的任何地方执行此操作),我编写了以下代码:

mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(!mDrawerToggle.isDrawerIndicatorEnabled()) {
            getActivity().onBackPressed();
        }
    }
});

现在每次按下 android.id.home 且未显示汉堡符号时,都会调用父 activity 的 onBackPressed()

在我的例子中,这是一个顺序问题,我需要先设置工具栏,然后再设置点击监听器。按此顺序:

       //works
    setSupportActionBar(myToolbar);

    myToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            openDrawer(view);
        }
    });

而不是这个:

    //doesn't work
    myToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            openDrawer(view);
        }
    });
    setSupportActionBar(myToolbar);

我们可以使用动画。

ValueAnimator drawerAnimator = ValueAnimator.ofFloat(Constants.HAMBURGER, Constants.BACK);
drawerAnimator.addUpdateListener(drawerAnimationUpdateListener);
drawerAnimator.setDuration(Constants.DRAWER_ANIMATION_DURATION);
drawerAnimator.setInterpolator(new LinearInterpolator());

为 HAMBURGER 图标传递操作 0,为 BACK 传递 1。

public void updateNavigationDrawer(int action) {
    drawerArrowDrawable = actionBarDrawerToggle.getDrawerArrowDrawable();
    if (action == Constants.BACK) {
        actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
        actionBarDrawerToggle.setHomeAsUpIndicator(drawerArrowDrawable);
        actionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //onBackPress();
            }
        });
       drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED););
    } else {
        actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    }
    if (drawerArrowDrawable.getProgress() != action) {
        if (action == Constants.BACK) {
            drawerAnimator.start();
        } else {
            drawerAnimator.reverse();
        }
    }
}