【问题标题】:Android lollipop toolbar switch between open/close drawer and back buttonAndroid棒棒糖工具栏在打开/关闭抽屉和后退按钮之间切换
【发布时间】:2014-12-27 13:56:49
【问题描述】:

我有标准的导航抽屉,但现在我正在尝试使用工具栏对其进行修改。

之前我的代码如下所示: MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Log.v("MAIN", "CREATE");
    initViews();
    setListeners();

    getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            shouldDisplayHomeUp();
        }
    });

    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getFragmentManager().findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));
}

NavigationDrawerFragment.java

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

    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

    ((MainActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    ((MainActivity) getActivity()).getSupportActionBar().setHomeButtonEnabled(true);

    mDrawerToggle = new ActionBarDrawerToggle(getActivity(), mDrawerLayout,
            ((MainActivity) getActivity()).getToolbar(),
            R.string.navigation_drawer_open,
            R.string.navigation_drawer_close) {
        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
            if (!isAdded()) {
                return;
            }

            getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }

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

            if (!mUserLearnedDrawer) {
                // The user manually opened the drawer; store this flag to prevent auto-showing
                // the navigation drawer automatically in the future.
                mUserLearnedDrawer = true;
                SharedPreferences sp = PreferenceManager
                        .getDefaultSharedPreferences(getActivity());
                sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
            }
            if (mDrawerListView != null) {

            }
            getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            super.onDrawerSlide(drawerView, slideOffset);
        }
    };

    // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
    // per the navigation drawer design guidelines.
    if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
        mDrawerLayout.openDrawer(mFragmentContainerView);
    }

    // Defer code dependent on restoration of previous instance state.

    mDrawerToggle.setDrawerIndicatorEnabled(true);

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

    mDrawerLayout.setDrawerListener(mDrawerToggle);
}

现在我修改了我的代码: MainActivity.java

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mToolbar = (Toolbar) findViewById(R.id.toolbar);

    if (mToolbar != null) {
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    initViews();
    setListeners();

    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getFragmentManager().findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));


    shouldDisplayHomeUp();

    getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            mBackCount++;
            shouldDisplayHomeUp();
        }
    });
}

NavigationDrawerFragment.java

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

    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

    mDrawerToggle = new ActionBarDrawerToggle(getActivity(), mDrawerLayout,
            ((MainActivity) getActivity()).getToolbar(),
            R.string.navigation_drawer_open,
            R.string.navigation_drawer_close) {
        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
            if (!isAdded()) {
                return;
            }

            getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }

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

            if (!mUserLearnedDrawer) {
                // The user manually opened the drawer; store this flag to prevent auto-showing
                // the navigation drawer automatically in the future.
                mUserLearnedDrawer = true;
                SharedPreferences sp = PreferenceManager
                        .getDefaultSharedPreferences(getActivity());
                sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
            }
            if (mDrawerListView != null) {

            }
            getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            super.onDrawerSlide(drawerView, slideOffset);
        }
    };

    // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
    // per the navigation drawer design guidelines.
    if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
        mDrawerLayout.openDrawer(mFragmentContainerView);
    }

    // Defer code dependent on restoration of previous instance state.

    mDrawerToggle.setDrawerIndicatorEnabled(true);

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

    mDrawerLayout.setDrawerListener(mDrawerToggle);
}

以及shouldDisplayHomeUp功能:

public void shouldDisplayHomeUp (){
    boolean canBack = getFragmentManager().getBackStackEntryCount() > 0;
    mNavigationDrawerFragment.getDrawerToggle().setDrawerIndicatorEnabled(!canBack);
}

但是没有显示后退箭头

我试过打电话

getSupportActionBar().setDisplayHomeAsUpEnabled(canBack);
getSupportActionBar().setHomeButtonEnabled(canBack);

所以后退箭头出现,但点击它没有效果

【问题讨论】:

  • 当你的 backstack 上有多个 Fragment 时,你想改变后退箭头吗?
  • 是的,并提供返回导航而不是打开抽屉
  • 与操作栏完美结合
  • 在这里查看我的答案stackoverflow.com/a/29292130/746347

标签: android navigation navigation-drawer android-appcompat android-toolbar


【解决方案1】:

来自文档:

要允许使用操作栏中的应用图标向上导航,请调用 setDisplayHomeAsUpEnabled():

@Override public void onCreate(Bundle savedInstanceState) {
     ...
     getActionBar().setDisplayHomeAsUpEnabled(true); }

这会在应用图标旁边添加一个左侧插入符号并将其作为操作启用 按钮,这样当用户按下它时,您的活动会收到一个 调用 onOptionsItemSelected()。该操作的 ID 是 android.R.id.home.

这意味着您必须在onOptionsItemSelected 上实现您的后台程序并检查R.id.home。为了避免在单击汉堡菜单时调用例程,请在 onOptionsItemSelected 上检查 canback

http://developer.android.com/training/implementing-navigation/ancestral.html#up

编辑

要归档您想要的内容,您必须实现自己的导航例程。

    mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(shouldBack()) {
               //call onbackpressed or something
                if(displayBackAgain)
                    return; //return after so you don't call syncState();       
            }else if (mNavigationDrawerFragment.isDrawerOpen())
                mNavigationDrawerFragment.closeDrawer();
            else
                mNavigationDrawerFragment.openDrawer();
            mNavigationDrawerFragment.getActionBarDrawerToggle().syncState();
        }
    });
}

要启用后退按钮图标,只需调用 getSupportActionBar().setDisplayHomeAsUpEnabled(true); 以禁用它,只需调用 mNavigationDrawerFragment.getActionBarDrawerToggle().syncState();

【讨论】:

  • 是的,但它不适用于来自 appcompat_v21 的工具栏
  • setNavigationOnClickListener 不捕获点击事件
  • 调用setup()后必须设置
  • 我遇到了 AppCompat v7 的问题。我可以很好地看到汉堡包图标,但是当我隐藏它并尝试显示家(向上可供性)时,它永远不会显示。想法?
  • @PedroOliveira 是的。这总是在 onPostCreate 中调用。我什至尝试再次调用它,但没有运气。这仅在将工具栏用作操作栏时发生。当我切换回不使用工具栏时,不再发生此问题。
【解决方案2】:

我找到了一种控制后退按钮和导航的方法。它对我有用。 首先,设置:

private void setupNav () {

    this.toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(this.toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    this.mActionBarDrawerToggle = new ActionBarDrawerToggle(this, this.mDrawerLayout, this.toolbar, 0, 0);

    this.mActionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //catch back button here.
        }
    });
    this.mDrawerLayout.setDrawerListener(this.mActionBarDrawerToggle);
    this.mActionBarDrawerToggle.syncState();
}

重要的是,这是我隐藏汉堡包并显示后退按钮的方式。您必须将此代码放在要显示后退按钮的位置。显示后退按钮时,我也会锁定导航。

if (!isShowBackButton) {
        mActionBarDrawerToggle.setDrawerIndicatorEnabled(true);
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    } else {

        mActionBarDrawerToggle.setDrawerIndicatorEnabled(false);
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        //enable back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

【讨论】:

  • 谢谢儿子,这对我有用并节省了很多时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多