Android棒棒糖工具栏在打开/关闭抽屉和后退按钮之间切换

时间:2014-10-31 09:35:27

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

我有标准导航抽屉,但现在我正在尝试使用工具栏修改它。

早些时候我的代码看起来像: 的 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);

因此后退箭头出现但点击它没有效果

2 个答案:

答案 0 :(得分:22)

来自文档:

  

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

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

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

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

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

答案 1 :(得分:3)

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

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