I just would like to tweak the View of an ActionBar MenuItem by code.
Unfortunately, it seems that getActionView always return null!
My code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = this.getSupportMenuInflater();
inflater.inflate(R.menu.folder, menu);
return super.onCreateOptionsMenu(menu);
}
public boolean onPrepareOptionsMenu(final Menu menu) {
MenuItem menuFolder = menu.findItem(R.id.menu_folder);
Log.i("", "* onPrepareOptionsMenu *" + menuFolder);
Log.i("", "* getActionView *" + menuFolder.getActionView());
Log is:
01-11 22:13:42.884: I/(7893): * onPrepareOptionsMenu
*com.actionbarsherlock.internal.view.menu.MenuItemWrapper#41401ac8
01-11 22:13:42.884: I/(7893): * getActionView *null
Thank a lot for any help
Edit:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_folder"
android:icon="#drawable/ic_menu_archive"
android:showAsAction="always"/>
</menu>
you should use
app:actionLayout="#layout/menu_actionbar_basket"
thats the trick
if you use
android:actionLayout="#layout/menu_actionbar_basket"
you would always get null exception in default toolbar.
getActionView() only works if there's a custom actionView from setActionView.
For me the solution that worked is to use app namespace instead of android.
app:actionViewClass="android.support.v7.widget.SearchView"
Don't forget to declare it:
xmlns:app="http://schemas.android.com/apk/res-auto"
First Solution
This happen may be you not set actionLayout in Menu file
so set your actionLayout in menu file
app:actionLayout="#layout/your_action_layout"
Second Solution
and the second solution is
from
android:actionLayout="#layout/your_action_layout"
to
app:actionLayout="#layout/your_action_layout"
If your debug build is working without any issues and issue is only with release build then this may be because of proguard configuration. If you have enabled proguard in your application then add below line to proguard-rules.pro
-keep class android.support.v7.widget.SearchView { *; }
in order to get the MenuItem View i use:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.someMenuItem:
View v = findViewById(R.id.someMenuItem);
doSomethingWithView(v);
break;
}
return super.onOptionsItemSelected(item);
}
Related
Trying to get searchview to work on app.
sdk min 17 max 22
testing on emulator api 18
menu xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never"/>
<item android:id="#+id/search"
android:icon="#drawable/ic_action_search"
android:title="#string/search_title"
app:showAsAction="ifRoom|collapseActionView"
android:orderInCategory="200"
app:actionViewClass="android.support.v7.widget.SearchView">
</item>
<item android:id="#+id/scan"
android:title="#string/scan"
android:showAsAction="ifRoom"
android:orderInCategory="300">
</item>
</menu>
onCreateOptionsMenu
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.material_toolbar, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
Log.d(TAG, "onQueryTextSubmit");
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
materialUpdate();
return false;
}
});
}
Running debug and looking at the search menu item shows action as null.
The layout display shows the android.support.v7.widget.SearchView as unknown xml attribute.
I am using Eclipse instead of Android Studio on this project.
Are you using Proguard or minify(ing) your code at some way?
https://code.google.com/p/android/issues/detail?id=58508
When you use a minify method like Proguard, classes and methods that you not access directly (but by some declarative way or reflexion) are removed. To avoid this, you need to instruct the build to specifically keep this classes/methods.
In this case, the SearchView class can be removed, because isn't directly called.
Try add this on your proguard rules file (check the right filename on your gradle file, at getDefaultProguardFile):
-keep class android.support.v7.widget.SearchView { *; }
This is how I added a SearchView to my menu (this is inside a Fragment):
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final MenuItem item = menu.add("Search");
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
final SearchView searchView = new SearchView(getActivity());
searchView.setOnQueryTextListener(this);
searchView.setIconifiedByDefault(true);
item.setActionView(mSearchView);
}
As an aside, I'd also recommend making the switch to Android Studio.
You are using support library. Try this:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search));
// ...
return true;
}
Not sure exactly what was wrong with what I had. It all appeared to be logical. I suspect that I had some misspelling are xmlns that was not correct. But it works the way I have it.
I appreciate the help but recommend that answers explain what you believe the problem is, what the fix is and why. It really helps the person learn.
MenuItemCompat is helper for accessing features in MenuItem introduced after API level 4 in a backwards compatible fashion. It is not necessary for this scenario.
Please keep answering questions it really does help
Thanks
I have the problem that my application doesn't show the options menu when I hit the menu button. Debugging shows that the onCreateOptionsMenu(Menu menu) method is not called after hitting the menu button. I have another application with the same code for the menu and there it works. So now my code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.app_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.options:
Intent intent = new Intent(this, OptionsActivity.class);
startActivityForResult(intent, 1);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
In res -> menu -> app_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/options" android:title="#string/options" />
</menu>
I have no idea why the onCreateOptionsMenu is not called after hitting the menu button. I hope you guys can help me.
Edit: I'm not using Fragments and the onCreateOptionsMenu is really never called. Not at the start of the app and not when i'm hitting the menu button on my device.
Not sure from your post that you're using Fragments. If so, you must set menu options on by
setHasOptionMenu(true);
call this method from Fragment's onCreate() and the options menu will then be shown.
Try to add these item attributes in your app_menu.xml file:
<item
android:id="#+id/options"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/options"/>
You must declare a string for options in Strings.xml
It will call when app starts for the first time not after menu item selected.
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (item.getItemId() == R.id.menuitem_id) {
}
return super.onMenuItemSelected(featureId, item);
}
this method will be called after selection
In Manifest file just set target versions as below:
android:minSdkVersion="8" android:targetSdkVersion="10"
This is my xml file for the ActionBar menu.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/fav_button"
android:title="Favourite"
android:icon="#drawable/unstar"
android:showAsAction="always|withText" />
</menu>
In my onCreate function, after calling setContentView. I do favButton = (MenuItem) this.findViewById(R.id.fav_button); But this returns null.
But returns the proper object on the onOptionsItemSelected function.
I'm using ActionBarSherlock, if that would make a difference.
I have tried various options suggested by other findViewById returns null questions, but they haven't solved my issue.
Instead of
favButton = (MenuItem) this.findViewById(R.id.fav_button);
in onCreateOptionsMenu after getMenuInflater().inflate(R.menu.activity_main, menu);
favButton = menu.findItem(R.id.fav_button);
Use menu.findItem() to get the menu. But this needs to be done after the menu is inflated.
Also, to answer your q in comment, you could use onPrepareOptionsMenu to set the state of your menu. If this menu is a one time updating, you could use onCreateOptionsMenu too, which is called only once.
but if someone really needs View and not MenuItem (for different manipulations, for example to start animation) you can still get it the next way:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.your_menu_xml_file, menu);
...
new Handler().post(new Runnable() {
#Override
public void run() {
view = findViewById(R.id.menu_refresh_button);
// view.startAnimation(animation);
}
});
return true;
}
Try
final Toolbar toolbar = findViewById(R.id.toolbar);
Menu menu=toolbar.getMenu();
MenuItem item = menu.findItem(R.id.'name id item');
for me works.
I don't know why, but in my case, I use findViewById(R.id.menu_id) return null. But I find that I use findViewById(item.getItemId) in onOptionsItemSelected, it return the view what we want.
I'm stuck while changing some properties on my options menu at onCreateOptionsMenu(). It seems like findItem() returns null, even though I'm pretty sure that the reference to the menu item is correct. My code looks as follows:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_profile, menu);
MenuItem leftie = menu.findItem(R.id.menu_profile);
leftie.setIcon(R.drawable.ic_menu_mapmode);
leftie.setTitle(R.string.back_map);
leftie.setIntent(authIntent);
return true;
}
I really don't know what can be wrong there. Thanks in advance :)
EDIT: I forgot to include the actual problem.
You can mention title and image for that menu item in XML.
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/newsItem"
android:icon="#drawable/news_tab"
android:title="#string/menu_news"/>
<item
android:id="#+id/dryiceItem"
android:icon="#drawable/dryice_tab"
android:title="#string/menu_dryice"/>
</menu>
and can set intent on menuItem like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.newsItem:
// start News activity
//write your intent here.
break;
case R.id.dryiceItem:
//start another activity
//write your intent here.
break;
}
}
I figured it out. The String that references to the menu index, R.menu.activity_profile was the wrong path so it was inflating an empty menu. I changed the string to R.menu.layout and now it works as expected.
System.out.println(menu.size());
MenuItem leftie = menu.findItem(R.id.menu_profile);
System.out.println(leftie);
leftie.setIcon(R.drawable.ic_menu_mapmode);
leftie.setTitle(R.string.back_map);
leftie.setIntent(authIntent);
I've also had this happen when I had a submenu that wasn't properly nested in item tags, like
<item />
<menu>
</menu>
or
<item >
<menu>
</menu>
<item>
Typecast your findItem statement with MenuItem
MenuItem leftie = (MenuItem) menu.findItem(R.id.menu_profile);
i have a menu that contains just one item.
Button exit;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
MenuInflater blowUp = getMenuInflater();
blowUp.inflate(R.menu.exitmenu, menu);
return true;
}
exit=(Button)findViewById(R.id.bexitMenuExit);
if i add listener to exit button , i got excpetion (null pointer), i am sure that there is no syntax error, the button exit is comming from this menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/bexitMenuExit"
android:title="Exit"
android:icon="#android:drawable/ic_menu_close_clear_cancel"
></item>
</menu>
what am i doing wrong?
There is no need to initialize Button and this doesn't make sence for me.
Just inflate your Menu and just override onOptionsItemSelected method:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
new MenuInflater(getApplicationContext()).inflate(R.menu.exitmenu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getId()) {
case R.id.bexitMenuExit:
// work that will start when you click on this
...
}
}
Also, there is no need to use OnClickListener, for this there is onOptionsItemSelected method and you should use it.
for menu items, as stated by Sajmon, you can use onOptionsIemsSelected function. onClickListener is used by views while this function has been designed to be used specifically by menu items using switch case.