Cannot catch toolbar home button click event

2019-01-04 09:15发布

I've implemented the newest appcompat library and using the Toolbar as action bar. But the problem is I cannot catch the home button / hamburger icon click event. I've tried and looked everything but doesn't seem to find a similar problem.

This is my Activity class :

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

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

    // Set up the drawer.
    navDrawerFragment = 
        (NavigationDrawerFragment) getSupportFragmentManager()
        .findFragmentById(R.id.navigation_drawer);
    navDrawerFragment.setUp(
        R.id.navigation_drawer, 
        (DrawerLayout) findViewById(R.id.drawer_layout), 
        toolbar);
}

And this is my NavigationDrawerFragment class :

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (savedInstanceState != null) {
        currentSelectedPosition = savedInstanceState.getInt(
            STATE_SELECTED_POSITION);
        fromSavedInstanceState = true;
    }

    // Select either the default item (0) or the last selected item.
    selectItem(currentSelectedPosition);
}

@Override
public void onActivityCreated (Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    // Indicate that this fragment would like 
    // to influence the set of actions in the action bar.
    setHasOptionsMenu(true);
}

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        drawerListView = (ListView) inflater.inflate(
            R.layout.fragment_navigation_drawer, container, false);
        drawerListView.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, 
                View view, int position, long id) {
                selectItem(position);
            }
        });
        //mDrawerListView.setAdapter();
        //mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
        return drawerListView;
}

public void setUp(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
    fragmentContainerView = getActivity().findViewById(fragmentId);
    this.drawerLayout = drawerLayout;

    // set a custom shadow that overlays the main 
    // content when the drawer opens
    drawerLayout.setDrawerShadow(
        R.drawable.drawer_shadow, GravityCompat.START);
    // set up the drawer's list view 
    // with items and click listener

    ActionBar actionBar = getActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setHomeButtonEnabled(true);

    // ActionBarDrawerToggle ties together the the proper interactions
    // between the navigation drawer and the action bar app icon.
    drawerToggle = new ActionBarDrawerToggle(
        getActivity(), 
        drawerLayout, 
        toolbar, 
        R.string.navigation_drawer_open, 
        R.string.navigation_drawer_close) {
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
        }

        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
        }
    };

    // If the user hasn't 'learned' about the drawer, 
    // open it to introduce them to the drawer,
    // per the navigation drawer design guidelines.
    if (!userLearnedDrawer && !fromSavedInstanceState) {
        drawerLayout.openDrawer(fragmentContainerView);
    }

    // Defer code dependent on restoration of previous instance state.
    drawerLayout.post(new Runnable() {
        @Override
        public void run() {
            drawerToggle.syncState();
        }
    });

    drawerLayout.setDrawerListener(drawerToggle);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(STATE_SELECTED_POSITION, currentSelectedPosition);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Forward the new configuration the drawer toggle component.
    drawerToggle.onConfigurationChanged(newConfig);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Log.d("cek", "item selected");
    if (drawerToggle.onOptionsItemSelected(item)) {
        Log.d("cek", "home selected");
        return true;
    }

    return super.onOptionsItemSelected(item);
}

when I clicked a menu item, the log "item selected" gets called. But when I click on the home button, it opens navigation drawer but the log "home selected" never get called. I've set onOptionsItemSelected method inside my Activity as well, but it still doesn't get called.

11条回答
Melony?
2楼-- · 2019-01-04 09:34

For anyone looking for a Xamarin implementation (since events are done differently in C#), I simply created this NavClickHandler class as follows:

public class NavClickHandler : Java.Lang.Object, View.IOnClickListener
{
    private Activity mActivity;
    public NavClickHandler(Activity activity)
    {
        this.mActivity = activity;
    }
    public void OnClick(View v)
    {
        DrawerLayout drawer = (DrawerLayout)mActivity.FindViewById(Resource.Id.drawer_layout);
        if (drawer.IsDrawerOpen(GravityCompat.Start))
        {
            drawer.CloseDrawer(GravityCompat.Start);
        }
        else
        {
            drawer.OpenDrawer(GravityCompat.Start);
        }
    }
}

Then, assigned a custom hamburger menu button like this:

        SupportActionBar.SetDisplayHomeAsUpEnabled(true);
        SupportActionBar.SetDefaultDisplayHomeAsUpEnabled(false);
        this.drawerToggle.DrawerIndicatorEnabled = false;
        this.drawerToggle.SetHomeAsUpIndicator(Resource.Drawable.MenuButton);

And finally, assigned the drawer menu toggler a ToolbarNavigationClickListener of the class type I created earlier:

        this.drawerToggle.ToolbarNavigationClickListener = new NavClickHandler(this);

And then you've got a custom menu button, with click events handled.

查看更多
Root(大扎)
3楼-- · 2019-01-04 09:35

If you want to know when home is clicked is an AppCompatActivity then you should try it like this:

First tell Android you want to use your Toolbar as your ActionBar:

setSupportActionBar(toolbar);

Then set Home to be displayed via setDisplayShowHomeEnabled like this:

getSupportActionBar().setDisplayShowHomeEnabled(true);

Finally listen for click events on android.R.id.home like usual:

@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
    if (menuItem.getItemId() == android.R.id.home) {
        Timber.d("Home pressed");
    }
    return super.onOptionsItemSelected(menuItem);
}

If you want to know when the navigation button is clicked on a Toolbar in a class other than AppCompatActivity you can use these methods to set a navigation icon and listen for click events on it. The navigation icon will appear on the left side of your Toolbar where the the "home" button used to be.

toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_nav_back));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d("cek", "home selected");
    }
});

If you want to know when the hamburger is clicked and when the drawer opens, you're already listening for these events via onDrawerOpened and onDrawerClosed so you'll want to see if those callbacks fit your requirements.

查看更多
男人必须洒脱
4楼-- · 2019-01-04 09:35

I have handled back and Home button in Navigation Drawer like

public class HomeActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {
    private ActionBarDrawerToggle drawerToggle;
    private DrawerLayout drawerLayout;
    NavigationView navigationView;
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_home);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        resetActionBar();

        navigationView = (NavigationView) findViewById(R.id.navigation_view);
        navigationView.setNavigationItemSelectedListener(this);

        //showing first fragment on Start
        getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).replace(R.id.content_fragment, new FirstFragment()).commit();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        //listener for home
        if(id==android.R.id.home)
        {  
            if (getSupportFragmentManager().getBackStackEntryCount() > 0)
                onBackPressed();
            else
                drawerLayout.openDrawer(navigationView);
            return  true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
       if (drawerLayout.isDrawerOpen(GravityCompat.START)) 
            drawerLayout.closeDrawer(GravityCompat.START);
       else 
            super.onBackPressed();
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Begin the transaction

        Fragment fragment = null;
        // Handle navigation view item clicks here.
        int id = item.getItemId();
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (id == R.id.nav_companies_list) {
            fragment = new FirstFragment();
            // Handle the action
        } 


        // Begin the transaction
        if(fragment!=null){

            if(item.isChecked()){
                if(getSupportFragmentManager().getBackStackEntryCount()==0){
                    drawer.closeDrawers();
            }else{
                    removeAllFragments();
                    getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE).replace(R.id.WikiCompany, fragment).commit();
                    drawer.closeDrawer(GravityCompat.START);
                }

            }else{
                removeAllFragments();
                getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE).replace(R.id.WikiCompany, fragment).commit();
                drawer.closeDrawer(GravityCompat.START);
            }
        }

        return true;
    }

    public void removeAllFragments(){
        getSupportFragmentManager().popBackStackImmediate(null,
                FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

    public void replaceFragment(final Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.WikiCompany, fragment).addToBackStack("")
                .commit();
    }


    public void updateDrawerIcon() {
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    Log.i("", "BackStackCount: " + getSupportFragmentManager().getBackStackEntryCount());
                    if (getSupportFragmentManager().getBackStackEntryCount() > 0)
                        drawerToggle.setDrawerIndicatorEnabled(false);
                    else
                        drawerToggle.setDrawerIndicatorEnabled(true);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }, 50);
    }

    public void resetActionBar()
    {
        //display home
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
    }

    public void setActionBarTitle(String title) {
        getSupportActionBar().setTitle(title);
    }
}

and In each onViewCreated I call

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ((HomeActivity)getActivity()).updateDrawerIcon();
    ((HomeActivity) getActivity()).setActionBarTitle("List");
}
查看更多
贪生不怕死
5楼-- · 2019-01-04 09:39

I think the correct solution with support library 21 is the following

// action_bar is def resource of appcompat; 
// if you have not provided your own toolbar I mean  
Toolbar toolbar = (Toolbar) findViewById(R.id.action_bar);
if (toolbar != null) {
    // change home icon if you wish
    toolbar.setLogo(this.getResValues().homeIconDrawable());
    toolbar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //catch here title and home icon click                          
        }                       
    });                 
}
查看更多
Explosion°爆炸
6楼-- · 2019-01-04 09:41
    mActionBarDrawerToggle = mNavigationDrawerFragment.getActionBarDrawerToggle();
    mActionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // event when click home button
        }
    });

in mycase this code work perfect

查看更多
小情绪 Triste *
7楼-- · 2019-01-04 09:42

In my case I had to put the icon using:

toolbar.setNavigationIcon(R.drawable.ic_my_home);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);

And then listen to click events with default onOptionsItemSelected and android.R.id.home id

查看更多
登录 后发表回答