androidandroid-toolbarnavigationitem

Navigation icon toast hint


Android toolbar menu items show toast hints on long press. The toast message is defined in xml with "title" attribute:

<item
    android:id="@+id/openRightMenu"
    android:orderInCategory="300"
    android:title="@string/navigation_drawer_right_desc"
    android:icon="@drawable/menu24_2"
    app:showAsAction="always"
    />

Can i set the same behaviour for the toolbar's navigation icon? I set the icon with the following code

        toolbar.setNavigationIcon(R.drawable.locations_icon);

but i can't set the description text here


Solution

  • There are two ways I've used to get a Toolbar's Navigation Button View. The first uses reflection on the Toolbar class, and the second iterates over a Toolbar's child Views until it finds an ImageButton.

    The reflective method:

    private View getNavButtonView(Toolbar toolbar) {
        try {
            Class<?> toolbarClass = Toolbar.class;
            Field navButtonField = toolbarClass.getDeclaredField("mNavButtonView");
            navButtonField.setAccessible(true);
            View navButtonView = (View) navButtonField.get(toolbar);
    
            return navButtonView;
        }
        catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    
        return null;
    }
    

    And the iterative method:

    private View getNavButtonView(Toolbar toolbar) {
        for (int i = 0; i < toolbar.getChildCount(); i++)
            if (toolbar.getChildAt(i) instanceof ImageButton)
                return toolbar.getChildAt(i);
    
        return null;
    }
    

    Please note that if you use the iterative method, it should be called immediately after setting the Navigation Icon, which should be called before any other Views are added or set on the Toolbar.

    After we've gotten the View, we just need to set an OnLongClickListener on it, and show the Toast with an appropriate offset. For example:

    toolbar.setNavigationIcon(R.drawable.ic_launcher);
    View navButtonView = getNavButtonView(toolbar);
    
    if (navButtonView != null) {
        navButtonView.setOnLongClickListener(new OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    Toast toast = Toast.makeText(v.getContext(),
                                                 "Navigation Button View",
                                                 Toast.LENGTH_SHORT);
    
                    int[] loc = new int[2];
                    v.getLocationOnScreen(loc);
    
                    toast.setGravity(Gravity.TOP | Gravity.LEFT,
                                     loc[0] + v.getWidth() / 2,
                                     loc[1] + v.getHeight() / 2);
                    toast.show();
    
                    return true;
                }
            }
        );
    }