工具栏 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 解决方案的启发,但您只需要做一次,一切就绪。
在我的 NavigationDrawer
的 setUp()
中(或者您可以在初始化 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();
}
}
}
我正在将操作栏换成工具栏,而且我几乎已经准备好了所有拼图。我的问题特别是如果我导航 '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 解决方案的启发,但您只需要做一次,一切就绪。
在我的 NavigationDrawer
的 setUp()
中(或者您可以在初始化 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();
}
}
}