I have a "menu" resource "menu_test" with the following code:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".TestActivity" >
<item android:id="#+id/hideshow"
android:title="Body visbility"
android:orderInCategory="100"
android:icon="#drawable/showicon"
app:showAsAction="always" />
</menu>
In my activity.java I inflate the toolbar in the "onCreate" function and add a click listener:
private Toolbar toolbar;
...
toolbar = (Toolbar)findViewById(R.id.toolbarId);
toolbar.inflateMenu(R.menu.menu_test);
toolbar.setOnMenuItemClickListener(this);
I would like to get the ID of "hideshow" and change the icon:
testItem = (MenuItem) toolbar.findViewById(R.id.hideshow);
testItem.setIcon(R.drawable.hideicon);
However to app crashes when getting the ID in the first line. In the click listener function it works fine, since the ID is provided internally with the click:
public boolean onMenuItemClick(MenuItem item)
item.setIcon(R.drawable.hideicon);
So how can I change the icon within the onCreate function? ("findItem" does not work, since toolbar is not a menu)
I may be easier to add the menu items programmatically so you can maintain a reference to them:
public class MainActivity extends AppCompatActivity {
private static final int MENU_SETTINGS = Menu.FIRST;
MenuItem menuItem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menuItem = menu.add(0, MENU_SETTINGS, 0, R.string.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_SETTINGS:
// DO SOMETHING
break;
}
return super.onOptionsItemSelected(item);
}
}
As the other answers and comments indicate, one needs a reference from onCreateOptionsMenu or onPrepareOptionsMenu.
In my case, this would require a lot of code rewrite, as this is an old project, where everything is based on using toolbars instead of menus.
However, I found an easy solution:
Instead of finding the ID and changing the icon, I created several instances of menu_test[1 .. n].xml with different icons and simply use inflateMenu(R.menu.menu_test[1 .. n]) depending on the icon I need.
If you write new code, use the solution from Abtin Gramian, so I mark that as the proper answer.
Related
I started my project with the template "Tabbed Activity" and am now trying to add an options menu. I have done this before with a blank activity and it worked fine. As far as I can tell I have done all the same steps, even as outlined by the documentation: https://developer.android.com/guide/topics/ui/menus#options-menu
When I run the app, nothing shows up. I would expect to see the 3 dots icon. I also tried adding icons to see if they would show up as actions. No luck. Here's what I've got in my MainActivity.java file:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu_layout, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.settingsMenuItem:
ShowSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void ShowSettings() {
// TODO show settings
}
}
And this is the options menu xml file which is "options_menu_layout.xml" located in the res/menu directory:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/settingsMenuItem"
android:icon="#drawable/baseline_settings_black_48"
android:title="#string/menu_option_settings"/>
</menu>
This seems to work on a blank activity, but not in this tabbed activity. Is there something I'm missing that is required to make these compatible?
show the xml, style and manifest files.
According to the documentation of onCreateOptionsMenu(),
"You must return true for the panel to be displayed; if you return false it will not be shown."
In your code sample, you have return super.onCreateOptionsMenu(menu);.
Is there a reason for calling the parent's class method as well? (The android developer guide code sample also does a return true;)
So I would first try to change onCreateOptionsMenu() to return true; to see if the options menu shows up and as a next step investigate the need to call the parent class' super.onCreateOptionsMenu(menu).
Turns out when using the template "Tabbed Activity" the manifest file uses a "NoActionBar" version of the theme.
I deleted the last part of this line:
android:theme="#style/Theme.ExampleApp.NoActionBar">
So it is this instead:
android:theme="#style/Theme.ExampleApp">
I'm trying to use the following xml to inflate my toolbar
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar"
style="?toolbarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="#menu/report_list"
app:navigationIcon="#drawable/ic_nav_back"
app:subtitle="#string/select_create_report"
app:title="#string/damage_reports" />
</com.google.android.material.appbar.AppBarLayout>
I can locate the toolbar inside my inflated xml like so:
mToolbar = findViewById(R.id.toolbar)
and the menu shows correctly
my problem is that since I haven't inflated the toolbar through onCreateOptionsMenu I can't use onOptionsItemSelected to handle events.
so I decided to add straight listeners to the different menu items.
but the thing is that I can't get a reference to them, when I use
mToolbar.findViewById(R.id.search_reports)
it returns null (which frankly I expected) but when I also use
mToolbar.menu.findItem(R.id.search_reports)
I also get null
however when I inspect mToolbar.actionItems[0] I see that the SearchView's string representation shows that its id is
androidx.appcompat.widget.SearchView{c1aeba0 VFE...... ......I. 0,0-0,0 #7f0800fb app:id/search_reports}
and mId from that action item is 2131230971 which translates to 7F0800FB which when searching inside build/generated points to
public static final int search_reports=0x7f0800fb;
but when I inspect R.id.search_reports instead of 2131230971 (which would make the findMenuItem work) I get -1000038
is there something wrong with the setup of my application? or is there a different way to find a specific menu item
edit: as a side note this seems to work
mToolbar.setOnMenuItemClickListener(this::menuItemClicked)
private fun menuItemClicked(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.search_reports -> {
vm.search_stuff()
true
}
else -> false
}
but I would still like to know why findItem does not work
edit 2: for those that may come upon this, it seems that during evaluation and debugging the resource numbers are indeed different, but if you actually place mToolbar.menu.findItem(R.id.search_reports) in your code and run it , it will work, even though it does not work while debugging
You can set click listener on item like this:
Toolbar toolbar = findViewById(R.id.toolbar);
//remember your menu item id !! mine is R.id.psMenuRefresh
toolbar.getMenu().findItem(R.id.psMenuRefresh).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
Log.i("mytag","helooo");
return false;
}
});
There you go.
You need add: onCreateOptionsMenu(Menu menu) and onOptionsItemSelected(MenuItem item) in your activity like this:
The first method it used to inflate menu.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
The second to add listeners:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_share) {
// YOUR CODE HERE ...
return true;
} else if (id == R.id.action_save) {
// YOUR CODE HERE ...
return true;
}
return super.onOptionsItemSelected(item);
}
I'm inflating the menu and trying to find the view of one of the menu items in the following way:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
// will print `null`
Log.i("TAG", String.valueOf(findViewById(R.id.action_hello)));
return true;
}
In the result null is printed in Logcat. However if I add some delay before calling findViewById, it returns correct View object:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(final Void... voids) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(final Void aVoid) {
// will print correctly android.support.v7.view.menu.ActionMenuItemView...
Log.i("TAG", String.valueOf(findViewById(R.id.action_hello)));
}
}.execute();
return true;
}
Of course this solution is very dirty and the minimal delay is unknown. Is there a way to register some callback for the menu inflated event. In other words: how can I call findViewById with the menu item id to be sure that the view is already there and this call won't return null?
Just override public void onPrepareOptionsMenu(Menu menu).
Documentation says:
This is called right before the menu is shown, every time it is shown.
You can use this method to efficiently enable/disable items or
otherwise dynamically modify the contents.
The view for Menu is created after calling onCreateOptionsMenu(Menu), that's why you can't access it subviews.
There are two ways to find the menu item view.
Frist way:-
Add a actionViewClass in your menu item, so that you can get view returned by getActionView. As getActionView() only works if there's a actionView defined for menuItem.
Add this in your menu item xml:-
<item
android:id="#+id/menuAdd"
android:icon="#android:drawable/ic_menu_add"
android:title="Add"
app:showAsAction="always"
app:actionViewClass="android.widget.ImageButton" />
In onCreateOptionsMenu method:-
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_item,menu);
View menuView=menu.findItem(R.id.menuAdd).getActionView();
Log.e("TAG", "onCreate: "+menuView );
return true;
}
Second way:-
The second way is to use a handler. Using this method you won't need to specify the time for the delay. Check the answer given by #davehenry here
You must call the super method when your code is finished or things just don't work as expected.
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
super.onCreationOptionsMenu(menu);
// calling the super completes the method now you code.
Log.i("TAG", String.valueOf(findViewById(R.id.action_hello)));
return true;
}
This way you get the menu item's id and its actionview:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
MenuItem mi = menu.findItem(R.id.action_hello);
int id = mi.getItemId();
Log.i("TAG", String.valueOf(id));
View actionView = mi.getActionView();
if (actionView == null) {
Log.i("TAG", "ActionView is null");
} else {
Log.i("TAG", "ActionView is NOT null");
}
return true;
}
Posting Runnable to the Handler queue would usually have that Runnable executed after the main UI thread finished with the currently being executed method part of the Activity's lifecycle, hence it would be a good chance to get what you want there. I do need to note that it's a trick which could fail if underestimated and not well tested but it has worked for me ever since I figured it out.
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
new Handler(getMainLooper()).post(new Runnable() {
#Override
public void run() {
Logger.LogI(TAG, "run: " + findViewById(R.id.action_hello));
}
});
return true;
}
Create a global variable for future use:
private ImageButton actionHelloView;
Then, in your onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
actionHelloView = (ImageButton) menu.findItem(R.id.action_hello).getActionView();
Log.i("the view is: ", String.valueOf(actionHelloView));
return true;
}
Put this in your XML:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.test.teststack.MainActivity">
<item
android:id="#+id/action_hello"
android:title="#string/action_settings"
app:showAsAction="never"
app:actionViewClass="android.widget.ImageButton"/>
</menu>
Note:
depending on your API version, you can switch between app:actionViewClass and android:actionViewClass in your xml.
Result in LOGCAT:
07-25 17:55:07.138 9491-9491/? I/the view is:: android.widget.ImageButton{5542a5c VFED..C.. ......I. 0,0-0,0 #7f080011 app:id/action_hello}
You don't mention why you want to find the menu item view and that may have some bearing on the answer that you are looking for. However, if you want to use findViewById() to find a menu view then this is one way to do it. The following example just changes a menu icon from an "X" to a check mark.
ViewTreeObserver.OnGlobalLayoutListener will be invoked right after layout of the toolbar in the following code. It is along the same lines as your delay, but it is the acceptable way to do this type of processing.
Alternately, the program can invoke menu.findItem(R.id.action_hello) in onPrepareOptionsMenu(). Unfortunately, the toolbar is not fully formed at this point, so a findViewById() will fail.
MainActivity.xml
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTitle("");
toolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
ActionMenuItemView view = toolbar.findViewById(R.id.action_hello);
if (view != null) {
// onGlobalLayout may be called before toolbar is fully defined.
Log.d("onGlobalLayout", "<<<<view is not null");
// Uncomment this view to make the change to the icon here. Android Studio
// will complain about a library group, but that can be ignored for this demo.
// view.animate() might be a better demo here.
view.setIcon(getResources().getDrawable(R.drawable.ic_check));
toolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Uncomment the following line to change the icon here.
// menu.findItem(R.id.action_hello).setIcon(getResources().getDrawable(R.drawable.ic_check));
return true;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_hello"
android:icon="#drawable/ic_x"
android:title="Item1"
app:showAsAction="ifRoom" />
</menu>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layoutDirection="ltr"
android:padding="0px"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:contentInsetEnd="0px"
app:contentInsetEndWithActions="0px"
app:contentInsetLeft="0px"
app:contentInsetRight="0px"
app:contentInsetStart="0px"
app:contentInsetStartWithNavigation="0px"
app:logo="#null"
app:title="#null"
app:titleMargin="0px"
app:titleTextColor="#757575"
tools:ignore="UnusedAttribute"
tools:title="toolbar">
</android.support.v7.widget.Toolbar>
</FrameLayout>
In onCreateOptionsMenu(), when you call
findViewById(R.id.action_hello)
this searches in the View hierarchy starting with your "content root". Since the menu you inflated hasn't been attached to the content root yet, it is likely this will return null.
You should be able to post a Runnable to a Handler that will find the View you want. This should be called after you return from onCreateOptionsMenu() and Android has attached the menu views to the content root. You shouldn't need any delay. You just need to wait until the framework has completed the creation of the options menu.
Inflating your menu is not asynchronous, so you are able to find the item exactly where you are doing so - although onPrepareOptionsMenu is probably the more correct place to do so.
What you cannot do is use findItemById, which looks in the currently showing layout (not your collapsed menu), instead you must use menu.findItem() (or menu.getItem())
If you really need to work with the view of the Item (vs the MenuItem object) you can use menu.findItem().getActionView()
I have a Toolbar within my app which I would like to modify it contents dynamically, during the app execution (in other words, on run-time).
For example, the app is capable of taking and previewing photos; once that photos are previewed, the user is able to select some photos and perform a sending action to a server. I want also to make the user able to delete photos once that some of them are selected and for doing that I would like that the "delete" item on the action bar (identifiable via the trash icon) will be visible only when one or more photos are selected.
Is this possible to do?
If yes, how?
In other words and, more generically, I want to control items (visibility) in the toolbar, setting the code as they will be "visible" only when some conditions are "true" (in the example above, when photos are selected or, in a different example, when user is logged) and invisible when they are "false" (when user isn't logged).
For now I just need to "remove" (or make invisible) items in the Toolbar, but it will be useful also to know if is possible to add items in the toolbar on run-time.
I'm adding some code which can help to understand the problem.
app_bar.xml file in "/res/layout", which graphically defines the Toolbar
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
android:theme="#style/ToolbarTheme" />
menu_resources.xml file, which defines the Toolbar items
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- "User favourite function", should appear as action button if possible -->
<item
android:id="#+id/action_app_icon"
android:icon="#mipmap/ic_launcher"
android:title="#string/action_bar_app_icon"
app:showAsAction="always" />
<!-- Settings, should always be in the overflow -->
<item
android:id="#+id/action_delete"
android:icon="#drawable/trash"
android:title="#string/action_bar_delete"
app:showAsAction="always"/>
<!-- Settings, should always be in the overflow -->
<item
android:id="#+id/action_settings"
android:icon="#drawable/settings"
android:title="#string/action_bar_settings"
app:showAsAction="never"/>
<!-- About, should always be in the overflow -->
<item
android:id="#+id/about"
android:icon="#android:drawable/ic_dialog_info"
app:showAsAction="never"
android:title="#string/action_bar_about"/>
Part of the activity in which the toolbar is
public class myClass extends AppCompatActivity implements View.OnClickListener {
// Instantiating a toolbar
private Toolbar toolbar;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_class);
// Adding toolbar to the activity
toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
// Get a support ActionBar corresponding to this toolbar
ActionBar ab = getSupportActionBar();
// Enable the Up button
ab.setDisplayHomeAsUpEnabled(true);
}
// The method that creates an options menu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_resource, menu);
// This make the delete item invisible
menu.findItem(R.id.action_delete).setVisible(false);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
// Perform the settings action
return true;
case R.id.about:
// Perform the about
return true;
case R.id.action_delete:
deletePhotos();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public static void manageSelection(Boolean state, int position){
if (photoArray.getNumberSelected() == 0) {
// disable the trash icon and its functionality;
} else {
// enable the trash icon with its functionality;
}
}
// This method allows to deleteItems images to the array
public void deletePhotos() {
//code for deleting photos
}
}
Thanks for your time.
Try this code in your activity please:
public class ActivityClass extends AppCompatActivity {
MenuItem menuItem; // Make global toolbar's menuItem
.
.
.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_layout, menu);
menuItem = menu.findItem(R.id.toolbar_action_button) // Your toolbar´s button ID and save it in your global menuItem
return super.onCreateOptionsMenu(menu);
}
public void showMenuItem(){
menuItem.setVisible(true); // Call this method in runtime when you need show it
}
public void hideMenuItem(){
menuItem.setVisible(false); // Call this method in runtime when you need hide it
}
[EDIT]
Thanks to Alessandro Iudicone´s comment we have an alternative way to get the toolbar´s menu too without the global MenuItem but only global Toolbar instance:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_layout, menu);
return super.onCreateOptionsMenu(menu);
}
public void showMenuItem(){
toolbar.getMenu().findItem(R.id.toolbar_action_button).setVisible(true);
}
public void hideMenuItem(){
toolbar.getMenu().findItem(R.id.toolbar_action_button).setVisible(false);
}
Hope it helps :)
For hiding the icon:
toolbar.findViewById(R.id.menu_item_id).setVisibility(View.INVISIBLE);
For adding a view to the toolbar:
TextView textView = new TextView(MainActivity.this);
textView.setText("Hello World");
toolbar.addView(textView);
This only works for views on the toolbar itself, not for the overflow menu. You'll probably have to use code found in this stack overflow answer if you want to mess with the overflow menu: Android Toolbar overflow menu view id
In AA+AppCompat, I try to change below code in Activity to AA-style.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_done, menu);
MenuItem menuItem = menu.findItem(R.id.itemDone);
View menuView = MenuItemCompat.getActionView(menuItem);
mButtonQuestionPost = (Button) menuView.findViewById(R.id.buttonMenuDone);
mButtonQuestionPost.setOnClickListener(this);
return super.onCreateOptionsMenu(menu);
}
First, changed head of Activity as below. The menu was shown as expected.
#EActivity(R.layout.activity_question_post)
#OptionsMenu(R.menu.menu_done)
public class QuestionPostActivity extends FragmentActivity {...
And, try to do button click method as below but nothing fired. I changed #Click with #OptionsItem or changed attributes this and that but no luck.
#Click(R.id.buttonMenuDone)
void buttonMenuDone(){
if (mQuestionPostFragment.validatePost()) {
setSupportProgressBarIndeterminate(true);
mQuestionPostFragment.postQuestion();
}
}
menu.xml is as below. Note that I'm using actionLayout for design purpose.
<item
android:id="#+id/itemDone"
android:title="#string/done"
app:showAsAction="always"
android:menuCategory="system"
app:actionLayout="#layout/item_menu_done"
/>
item_menu_done is as below.
<Button
android:layout_width="48dp"
android:layout_height="?actionBarSize"
android:id="#+id/buttonMenuDone"
android:text="#string/done"
android:textColor="#android:color/white"
android:textSize="14sp"
android:background="?attr/actionBarItemBackground"
/>
The AA-generated file does not have MenuItemCompat.getActionView(menuItem), but hardly to make it with AA. Can someone please help me?
I am afraid you cannot bind a listener with #Click to a menu action view, since Activity.findViewById cannot find that view inside the menu items. What you can do is injecting the menuitem, then, manually bind your listener as you already did.
#EActivity(R.layout.activity_question_post)
#OptionsMenu(R.menu.menu_done)
public class QuestionPostActivity extends FragmentActivity {
#OptionsMenuItem(R.id.menuItemDone)
MenuItem buttonMenuDone;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// this will be called by the generated subclass after it injected the menu
MenuItemCompat.getActionView(itemDone).findViewById(R.id.buttonMenuDone).setOnClickListener(this);
return true;
}
}
In case someone needs it, nowadays you can use the OptionsItem() annotation like so:
//Even with system items
#OptionsItem(android.R.id.home)
void onHomeItemClicked() {
finish();
}
//Or your custom ones
#OptionsItem(R.id.buttonMenuDone)
void onMenuDoneItemClicked() {
//Do your stuff
}