Control the Toolbar icon with NavigationDrawer

2020-05-08 23:25发布

问题:

I'm currently using within my app the android.support.v7.widget.Toolbar and android.support.v4.widget.DrawerLayout. Everything is working right, but there is a slight thing I want to change its behaviour.

When I open the drawer, the whole drawer occupies the space of the Toolbar. It would be nice that the Toolbar stays on top, like in the Google Music app. How can I achieve that?

But the most important thing isn't the previous. At first, the icon which is loaded in the application is the three stripped one. I've realised that after opening the drawer, the icon changes to an arrow. And after loading a fragment, the arrow remains there as the Toolbar icon, even if I press back until the first screen. How could I avoid the arrow appearing from after opening the drawer? I'd want to change this icon manually, specially when I load lower level fragments.

Thanks for your help!

Code:

public class HomeActivity extends BaseActivity {



...

    private DrawerLayout mDrawer;
    private ActionBarDrawerToggle mDrawerToggle;
    private ListView mDrawerList;
    private ListView mDrawerRightList;
    private RelativeLayout mDrawerRelativeLayout;
    private String[] mDrawerMenuTitles;
    private Toolbar mToolbar;

    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        mDrawerMenuTitles = getResources().getStringArray(R.array.main_menu_options);

        mDrawer = (DrawerLayout) findViewById(R.id.drawer);

        mDrawerRelativeLayout = (RelativeLayout) findViewById(R.id.theDrawerRelativeLayout);

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

        mDrawerRightList = (ListView) findViewById(R.id.theDrawerRight);
        mDrawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerRightList);

        mDrawerList = (ListView) findViewById(R.id.theDrawer);

        mDrawerList.setAdapter(new ArrayAdapter<String>(
                getSupportActionBar().getThemedContext(), 
                R.layout.drawer_list_item,
                mDrawerMenuTitles
        ));

        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

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

        setmToolbar((Toolbar) findViewById(R.id.toolbar));

        mDrawerToggle = new ActionBarDrawerToggle(
                this, 
                mDrawer,
                mToolbar,
                R.string.drawer_open, 
                R.string.drawer_close){

            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
                // TODO Auto-generated method stub
                super.onDrawerSlide(drawerView, slideOffset);
            }

            @Override
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                //getSupportActionBar().setTitle(CURRENT_FRAGMENT);
            }

            /** Called when a drawer has settled in a completely open state. */
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                //getSupportActionBar().setTitle("Configuración");
            }           

        };

        mDrawerToggle.setDrawerIndicatorEnabled(true);
        mDrawerToggle.syncState();
        mDrawer.setDrawerListener(mDrawerToggle);

        setToolbarSubtitle(getString(R.string.misrutas_titulo));

        initialisePreferences(savedInstanceState);

        if (savedInstanceState == null) {
            replaceFragment(DEFAULT_FRAGMENT);
        }

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                mDrawer.openDrawer(GravityCompat.START);
                return true;
        }

        return super.onOptionsItemSelected(item);
    }

     private class DrawerItemClickListener implements OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            //selectItem(position);
            final int thePos = position;
            mDrawer.setDrawerListener( new DrawerLayout.SimpleDrawerListener(){
                @Override
                public void onDrawerClosed(View drawerView){
                ....
                }
            });

            if(mDrawer.isDrawerOpen(GravityCompat.START))
                mDrawer.closeDrawer(mDrawerRelativeLayout);

        }
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

     @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggls
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public void onBackPressed(){
        setToolbarSubtitle(getString(R.string.app_name_subtitle));
      if (getSupportFragmentManager().getBackStackEntryCount() == 1){
        finish();
      }
      else {
        super.onBackPressed();
      }
    }

    private void replaceFragment (String to){

        if(!to.equalsIgnoreCase(CURRENT_FRAGMENT)){
            CURRENT_FRAGMENT = to;
            Fragment fragment = Fragment.instantiate(HomeActivity.this, to);
            String backStateName =  fragment.getClass().getName();
            String fragmentTag = backStateName;

            FragmentManager manager = getSupportFragmentManager();
            boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);

            if (!fragmentPopped && manager.findFragmentByTag(fragmentTag) == null){ //fragment not in back stack, create it.
                FragmentTransaction ft = manager.beginTransaction();
                ft.replace(R.id.content_frame, fragment, fragmentTag);
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                ft.addToBackStack(backStateName);
                ft.commit();
            } 

        }

    }

    //More methods
    ....

}

EDIT:

I have been able to modify a little bit my layout, so that the Toolbar stays on top of the rest screen (drawer and fragment). But I haven't been able to control the icon. When I open the drawer, the hamburger icon converts into the arrow. When I close the drawer, the arrow is converted into the hamburger. But when I press an option within the drawer, a new fragment is inflated and the hamburger icon is replaced by the arrow until the application is closed, so that the hamburger icon is never seen.

How can I adapt the icon behaviour so that it doesn't change from hamburger to arrow when I click over a drawer option?

回答1:

now I try to do a similiar navigation drawer as you... Basically respect me is that I had a diferent package for navigation drawer that I think so is different from your navigation drawer... My package is:

 //From android studio
 compile 'com.android.support:appcompat-v7:21.0.0'

I don't know if this can help you, but I follow this greatest tutorial and my navigation drawer work it's similar as you wish!

http://androideity.com/2013/12/16/android-navigation-drawer-parte-1/ http://androideity.com/2014/02/26/android-navigation-drawer-parte-2/

I wait that I help you! Good luck!

PD: If you have a problems with this tutorial or same advice me! :D



回答2:

At first glance seems that you are setting new drawer listener whenever item is selected, precisely in this snippet:

 private class DrawerItemClickListener implements OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            //selectItem(position);
            final int thePos = position;
            mDrawer.setDrawerListener( new DrawerLayout.SimpleDrawerListener(){
                @Override
                public void onDrawerClosed(View drawerView){
                ....
                }
            });

            if(mDrawer.isDrawerOpen(GravityCompat.START))
                mDrawer.closeDrawer(mDrawerRelativeLayout);

        }
    }

This snippet replaces ActionBarDrawerToggle (which implements DrawerListener as well), so no calls are made to ActionBarDrawerToggle which controls the icon.

How can I adapt the icon behaviour so that it doesn't change from hamburger to arrow when I click over a drawer option?

Relating to your previous statements, this sound vague to me. Why you'd be preventing this default behaviour? You can prevent morphing by not calling super calls in DrawerListener's methods.