onOptionsItemSelected not called when using actionLayout (SherlockActionBar)

Android

Android Problem Overview


The method onOptionsItemSelected isn't being called when using actionLayout in a menu item. Am I missing something, or is it a known problem with SherlockActionBar?

Activity

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.article, menu);
    
    super.onCreateOptionsMenu(menu);
    
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {   
	
	Log.d(TAG, "onOptionsItemSelected()");
	
	switch (item.getItemId()) {        
      	case android.R.id.home:            
      		finish();      
      		return true; 
      	case R.id.menu_item_comment:
      		return true;
      	default:            
      		return super.onOptionsItemSelected(item);    
	}
}

Menu

http://schemas.android.com/apk/res/android">

<item android:id="@+id/menu_item_comment"
    android:showAsAction="ifRoom"
    android:actionLayout="@layout/action_bar_comment_layout"/>

Android Solutions


Solution 1 - Android

well, you have to set onClickListener on that actionLayout to receive callback. I do it like this:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	getSupportMenuInflater().inflate(R.menu.map_menu, menu);
	for (int i = 0; i < menu.size(); i++) {
		MenuItem item = menu.getItem(i);
		if (item.getItemId() == R.id.menu_more) {
			itemChooser = item.getActionView();
			if (itemChooser != null) {
				itemChooser.setOnClickListener(this);
			}
		}
	}
	return super.onCreateOptionsMenu(menu);
}

Solution 2 - Android

You'll have to add your own OnClickListener and explicitly call onOptionsItemSelected:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuItem awesomeMenuItem = menu.findItem(R.id.action_awesome);
    View awesomeActionView = menuItem.getActionView();
    awesomeActionView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onOptionsItemSelected(awesomeMenuItem));
        }
    });
}

P.S: Don't know why it doesn't work out of the box.

Solution 3 - Android

You should use MenuItemCompat.getActionView(menuItem); instead of item.getActionView(); if you are developing for older version.

@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.menu, menu);
		for (int i = 0; i< menu.size() ;i++) {
			MenuItem menuItem = menu.getItem(i);
			if (menuItem.getItemId() == R.id.add_item) {
				View view = MenuItemCompat.getActionView(menuItem);
				if (view != null) {
					view.setOnClickListener(new OnClickListener() {
						
						@Override
						public void onClick(View v) {
							Intent intent = new Intent(MainActivity.this, ToDoActivity.class);
							startActivity(intent);
						}
					});
				}
			}
		}		
		return true;
	}

Solution 4 - Android

 override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.menu_add_require, menu)

    val menuItem = menu!!.findItem(R.id.menu_cart)
    val view = menuItem.actionView
    view.setOnClickListener {
        onOptionsItemSelected(menuItem)
    }

    return true
}

Working for me (code is in kotlin)

Solution 5 - Android

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.main, menu);
    View view = menu.findItem(R.id.menu_item_comment).getActionView();
    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // do something
        }
    });
    return true;
}

Also, (and that was very important for me, so other answers did not work) you need to disable the clickable option of all views in your action layout (that is, action_bar_comment_layout.xml):

android:clickable="false"

Solution 6 - Android

Combining @Arun Kumar's and @Luten's answers, the below method will make the implementation generic. For all the menu items using actionView, we setOnClickListener to call onOptionsItemSelected(item). This way we can mix and match normal and actionLayout menu items, without worrying about setting individual onClickListeners.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.clear();
    inflater.inflate(menuResourceId(), menu);

    for (int i = 0; i < menu.size(); i++) {
        final MenuItem item = menu.getItem(i);
        View actionView = MenuItemCompat.getActionView(item);
        if (actionView != null) {
            actionView.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    onOptionsItemSelected(item);
                }
            });
        }
    }

    super.onCreateOptionsMenu(menu, inflater);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser634545View Question on Stackoverflow
Solution 1 - AndroidTomislav NovoselecView Answer on Stackoverflow
Solution 2 - AndroidLutenView Answer on Stackoverflow
Solution 3 - AndroidArun KumarView Answer on Stackoverflow
Solution 4 - AndroidTijo ThomasView Answer on Stackoverflow
Solution 5 - AndroidAlexey TimokhinView Answer on Stackoverflow
Solution 6 - AndroidanemoView Answer on Stackoverflow