31

For specific customer requirement, I need to allow the user of my app ( won't be published in Market) to click on the ActionBar title to execute some actions.

I have been looking in the Android source, but I am not able to find an ID for the actionBar TextView title.

Is there a proper way to handle such clicks?

Waza_Be
  • 39,407
  • 49
  • 186
  • 260

3 Answers3

29

The title is non-clickable AFAIK. The icon/logo is clickable -- you'll get that via android.R.id.home in onOptionsItemSelected(). Conceivably, the title also routes this way, though they don't mention it and I wouldn't rely upon it.

It sounds like you want a Spinner for the user to choose the actions to execute. If so, use setListNavigationCallbacks(). If you want to remove the title as now being superfluous, use setDisplayOptions(0, DISPLAY_SHOW_TITLE).

If you want something other than a Spinner on the left side of the action bar, use setDisplayOptions(DISPLAY_SHOW_CUSTOM, DISPLAY_SHOW_CUSTOM) and setCustomView(). Note that this approach is not recommended ("Avoid using custom navigation modes in the action bar"), as it may not work well with phones, particularly in portrait mode.

Another possibility would be to remove the title and use a logo instead of the icon, and in the logo have your "title" as part of the image. The whole logo should be clickable, picked up via onOptionsItemSelected().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • You said you can detect the the event when the user clicked on the Android ActionBar logo by adding this : @Override public boolean onOptionsItemSelected (MenuItem item) { if(item.getItemId() == android.R.id.home) { //User clicked on the ActionBar logo } return true;// stop system processing } But for me this does not work. Also i tried with onTouchEvent X and Y of the event, (not great...) but this does not work either. I would appreciate if you could help me there – OlivierM Oct 17 '12 at 15:56
  • 9
    @OlivierM: You need to call `setHomeButtonEnabled()` on your `ActionBar` if you are running on Android 4.0 or higher. On Android 3.x, that method did not exist and was not needed. – CommonsWare Oct 17 '12 at 16:04
  • 4
    FYI, as of 4.2.2 title and icon are treated as one element. – Flynn81 Jun 20 '13 at 13:37
  • While I understand why you shouldn't implement your own "custom" navigation modes, how else could I set a specific type face for my title other than using setCustomView with my own TextViews in it? Not nice, really... – Zordid Jun 24 '13 at 11:10
  • 1
    But in whatsapp application you'l find the title is also clickable. – Rojesh Jan 27 '14 at 06:21
  • Spinners (ActionBar drop-down menus) are described here: http://developer.android.com/guide/topics/ui/actionbar.html#Dropdown – caw Feb 12 '14 at 05:48
  • Is it possible to both customize how the spinner (made by "setNavigationMode(ActionBar.NAVIGATION_MODE_LIST)" ) and also get a reference to it, in order to handle some operations on it programmatically ? – android developer May 22 '14 at 09:35
  • @androiddeveloper: There is no supported way to get the `Spinner`. Technically, it does not have to be implemented by a `Spinner` at all. – CommonsWare May 22 '14 at 11:11
  • @CommonsWare So it's best to use "setCustomView" and do things the way you want, right? I guess it's for the best. – android developer May 22 '14 at 11:38
  • @androiddeveloper: So long as you don't do something to cause your users to go "WTF?", sure. The risk of doing something *like* `NAVIGATION_MODE_LIST` without it actually *being* `NAVIGATION_MODE_LIST` is the "uncanny valley", where your approach differs in subtle ways that cause user angst. – CommonsWare May 22 '14 at 11:58
  • @CommonsWare I only considered using NAVIGATION_MODE_LIST because I didn't know of the setCustomView, so I planned on making it look like a title&subtitle , and handle clicking myself. It was supposed to be a workaround, and the UI would (as I planned) look the same. I do this for a company that wishes to have something like WhatsApp, which makes clicking on the title customize the current group. I said my opinion that it's a bit weird, but that's their choice. Anyway, "setCustomView" works fine so there is no need for this weird workaround (which I didn't even manage to make). – android developer May 22 '14 at 15:20
  • 1
    remember to setHasOptionsMenu(true); in the onCreate() of fragment to make onOptionsItemSelected() work. – Robert Sep 24 '14 at 07:54
10

//onCreate

ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowHomeEnabled(false);
        actionBar.setDisplayShowTitleEnabled(false);
//        View actionBarView = getLayoutInflater().inflate(R.layout.action_bar_custom_view, null);
        actionBar.setCustomView(actionBarView);
        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

//your logic for click listner
 setListenerForActionBarCustomView(actionBarView);

 private void setListenerForActionBarCustomView(View actionBarView) {
        ActionBarCustomViewOnClickListener actionBarCustomViewOnClickListener = new ActionBarCustomViewOnClickListener();
        actionBarView.findViewById(R.id.text_view_title).setOnClickListener(actionBarCustomViewOnClickListener);
}
 private class ActionBarCustomViewOnClickListener implements OnClickListener {
        public void onClick(View v) {       
        switch(v.getId()) {
            case R.id.text_view_title:

                //finish();
                break;
    }
}
Padma Kumar
  • 19,893
  • 17
  • 73
  • 130
  • 2
    Is it possible to mimic the exact way the action bar title&subtitle are shown, so that it would look like clicking on the normal ones ? – android developer May 21 '14 at 14:00
6

You can set up a custom toolbar from Support Library by declaring <android.support.v7.widget.Toolbar> in your layout (see Chris Banes' answer for full toolbar layout example).

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- We use a Toolbar so that our drawer can be displayed
             in front of the action bar -->
        <android.support.v7.widget.Toolbar
            android:id="@+id/my_awesome_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/main_toolbar" 
            android:minHeight="?attr/actionBarSize" />

       <FrameLayout 
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />


</LinearLayout>

After you can add on click listener in your activity just like to most other Views.

Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
toolbar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MyActivity.this, "Test", Toast.LENGTH_LONG).show();
            }
        });

If you want to capture touch events on title:

toolbar.setOnTouchListener(new View.OnTouchListener() {
            Rect hitrect = new Rect();
            public boolean onTouch(View v, MotionEvent event) {
                if (MotionEvent.ACTION_DOWN == event.getAction()) {
                    boolean hit = false;
                    for (int i = toolbar.getChildCount() - 1; i != -1; i--) {
                        View view = toolbar.getChildAt(i);
                        if (view instanceof TextView) {
                            view.getHitRect(hitrect);
                            if (hitrect.contains((int)event.getX(), (int)event.getY())) {
                                hit = true;
                                break;
                            }
                        }
                    }
                    if (hit) {
                        //Hit action
                    }
                }
                return false;
            }
        });
Community
  • 1
  • 1
Boris Treukhov
  • 17,493
  • 9
  • 70
  • 91