i have a note taking activity where i would like to be able to edit and save (basically overwrite) the same note.
Once i click the edit MenuItem, I would like it to hide and then show the save MenuItem.
I can get the edit MenuItem to be invisible but i cant get the save MenuItem to show. i keep getting a null pointer exception.
here's my edit_question_menu.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/edit_question"
android:icon="#drawable/ic_edit_black_24dp"
android:title="Edit"
app:showAsAction="ifRoom"
android:visible="true">
</item>
<item
android:id="#+id/save_question"
android:icon="#drawable/ic_save_black_24dp"
android:title="Edit"
app:showAsAction="ifRoom"
android:visible="false">
</item>
</menu>
activity.java file
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.edit_question_menu, menu);
MenuItem itemSave = menu.findItem(R.id.save_question);
itemSave.setVisible(false);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save_question:
saveQuestion();
return true;
case R.id.edit_question:
item.setVisible(false);
// MenuItem save_Question_MenuItem = findViewById(R.id.save_question);
// save_Question_MenuItem.setVisible(true);
enableEditMode();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void enableEditMode(){
MenuItem saveButton = findViewById(R.id.save_question);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_black_24dp);
questionEditText = findViewById(R.id.questionEditTextID);
mPostAnswerButton.setEnabled(false);
mPostAnswerButton.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
mCommentButton.setEnabled(false);
mCommentButton.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
saveButton.setVisible(true); **ERROR HAPPENS HERE**
}
Any and all help is appreciated. This seems fairly simple but I cant find a way to get it to work.
Add flag to your activity that indicates where the save MenuItem should be visible or not:
private boolean mShowSaveIcon
Override onPrepareOptionsMenu (UPDATE):
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.save_question);
item.setVisible(mShowSaveIcon);
menu.findItem(R.id.edit_question).setVisible(!mShowSaveIcon); // you can use negation of the same flag if one and only one of two menu items is visible; or create more complex logic
return true;
}
In the click handler, change flag value and request invalidation:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save_question:
mShowSaveIcon = false;
break;
case R.id.edit_question:
item.setVisible(false);
enableEditMode();
mShowSaveIcon = true;
break;
}
invalidateOptionsMenu();
return true;
}
Change handler:
private void enableEditMode(){
/// MenuItem saveButton = findViewById(R.id.save_question); // <--- NO THIS LINE
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_black_24dp);
questionEditText = findViewById(R.id.questionEditTextID);
mPostAnswerButton.setEnabled(false);
mPostAnswerButton.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
mCommentButton.setEnabled(false);
mCommentButton.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
/// saveButton.setVisible(true); **ERROR HAPPENS HERE** // <--- NO THIS LINE
}
I am trying to animate between the visibility mode for a menu.
By default all menu items are hidden but when the user clicks on the edit button i want to show all the items with an animation.
I have achieved the first part of changing the visibility of the menu items and that works fine but the animation part crashes the app.
Here is my code.
When user clicks on edit this is called.By default edit_mode is false.
if (!edit_mode) {
edit_mode = true;
supportInvalidateOptionsMenu();
}
This is the menu code.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_add__custom, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem photo = menu.findItem(R.id.photo);
photo.setVisible(edit_mode);
if (edit_mode)
photo.getActionView().animate().alpha(1.0f);
MenuItem date = menu.findItem(R.id.date);
date.setVisible(edit_mode);
if (edit_mode)
date.getActionView().animate().alpha(1.0f);
MenuItem done = menu.findItem(R.id.done);
done.setVisible(edit_mode);
if (edit_mode)
done.getActionView().animate().alpha(1.0f);
return edit_mode;
}
menu.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">
<item
android:id="#+id/date"
android:icon="#drawable/ic_event_white_24dp"
android:orderInCategory="200"
android:title="Date"
app:showAsAction="ifRoom" />
<item
android:id="#+id/done"
android:icon="#drawable/ic_done_white_24dp"
android:orderInCategory="300"
android:title="Done"
app:showAsAction="ifRoom" />
<item
android:id="#+id/photo"
android:icon="#drawable/ic_photo_white_24dp"
android:orderInCategory="100"
android:title="Done"
app:showAsAction="ifRoom" />
I sure that crash that you are having is there because of NullException thrown by getActionView(). First of all to animate that way you have set the actionView first during onCreateOptionMenu(). That way when you get the actionView in onPrepareOptionsMenu it wont crash because of that and then you can animate it. The onPrepareOptionsMenu executes when you press the menu button so your logic to animate it that time is correct.
If its just the text you want to show in menu item, it should go like this,
final MenuItem photo;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_my_report, menu);
photo = menu.findItem(R.id.action1);
TextView textView = new TextView(this);
textView.setText("I am menu item");
photo.setActionView(textView);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(someCondition)
{
photo.getActionView().animate().alpha(1.0f);
}
return super.onCreateOptionsMenu(menu);
}
In case you want to have the a complex and customise text you can set it using the layoutInflator service. This could go in your onCreate,
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView view = (ImageView)inflater.inflate(R.layout.some_view, null);
Animation rotation = AnimationUtils.loadAnimation(this, R.anim.fade);
and onCreateOptionMenu,
view.startAnimation(rotation);
photo.setActionView(view);
Its just to get you an idea what needed to be done, you can play around with this and can suit your need.
I'm busy with changing my existing app to material design, but i'm having trouble with the menu items inside the ActionBar.
First of all in some activities i'm using a searchview, But i have read that you need to use a custom prefix inside the searchview menu xml. So i did:
<?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_search"
android:icon="#drawable/ic_action_search_light"
android:title="Search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
But everytime I'm getting the error:
"Should use android:showAsAction when not using the appcompat library"
if i change app:showAsAction="ifRoom|collapseAction" to android:showAsAction="ifRoom|collapseActionView"
I'm not getting a searchview that take the whole lenght of the actionbar, just some strange square in the right corner where the items are placed. Here is my code of the onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.searchview, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView search = (SearchView) MenuItemCompat.getActionView(searchItem);
if(search != null)
{
search.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(search.getWindowToken(), 0);
try {
new LoadResultsTask().execute(URLEncoder.encode(query, "UTF-8"));
} catch (UnsupportedEncodingException e) {
Toast.makeText(IndexerOverviewActivity.this, "Could not parse Query", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
return true;
}
#Override
public boolean onQueryTextChange(String search) {
return true;
}
});
}
search.setIconifiedByDefault(false);
return super.onCreateOptionsMenu(menu);
}
I noticed aswell that all my actionbar menu items that has android:showsAsAction="always" are shown as android:showsAsAction="never" when i start my application on my device. So my first guess is it has everything to do with the prefix to use in the menu xml files.
Pffff, after just a single "clean" it works perfectly now...
It took me freaking 2 hours to fix this.
I want to get an item to only show text on the optionsMenu in the action bar.
Here is my code:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/select_recipients_return_to_compose"
android:showAsAction="ifRoom|withText"
android:orderInCategory="100"
android:title="Finish"/>
</menu>
Things I've tried:
1) True on onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.create_broadcast_options_menu, menu);
optionsMenu = menu;
MenuItem menuItem = menu.getItem(0);
menuItem.setEnabled(false);
// check if our roles recipients are chcked and if
Cursor cursor3 = getCheckedRecipients();
// actually, just checked if they're ticked.
if (cursor3 == null || cursor3.getCount() == 0) {
menuItem.setVisible(false);
} else {
menuItem.setVisible(true);
menuItem.setEnabled(true);
}
return true;
}
2) Setting the text manually
Anything else?
Right now it will show my home icon as the icon but will respond to clicks and behavior I set on onOptionsItemSelected().
android:showAsAction="withText|always"
forces the menuItem to the be a action of your actionbar.
if you want it to be in the overflow use
android:showAsAction="withText|never"
I want to add menu handler to my project. I read http://developer.android.com/guide/topics/ui/menus.html too, its very simple but the icon is not shown. I am very confused. I even added a menu item programmatically.
My code is:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 0, 0, "Quit").setIcon(R.drawable.ic_launcher);
getMenuInflater().inflate(R.layout.menu, menu);
return true;
}
and in xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Single menu item
Set id, icon and Title for each menu item
-->
<item android:id="#+id/menu_bookmark"
android:icon="#drawable/update"
android:title="#string/Update" />
</menu>
After Long try i found below solution which might help others to save there time. Basically, the solution provided by "lbarbosa", i like to thanks to him sincerely.
Tried this based on the previous answers and it works fine, at least with more recent versions of the support library (25.1):
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
if(menu instanceof MenuBuilder){
MenuBuilder m = (MenuBuilder) menu;
m.setOptionalIconsVisible(true);
}
return true;
}
If you're running your code on Android 3.0+, the icons in the menu are not shown by design. This is a design decision by Google.
You can read more about it in this on Android developers blog.
No matter what design choices where made by the system, you can circumvent this with the solution provided in the top upvoted answer to this question
Code below for completeness. Tested working on android.support.v7.app.ActionBarActivity
#Override
public boolean onMenuOpened(int featureId, Menu menu)
{
if(featureId == Window.FEATURE_ACTION_BAR && menu != null){
if(menu.getClass().getSimpleName().equals("MenuBuilder")){
try{
Method m = menu.getClass().getDeclaredMethod(
"setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
}
catch(NoSuchMethodException e){
Log.e(TAG, "onMenuOpened", e);
}
catch(Exception e){
throw new RuntimeException(e);
}
}
}
return super.onMenuOpened(featureId, menu);
}
Old question but hope it will help someone.
use the following code:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/menu_item_share"
android:title="Share"
app:showAsAction="always"
android:icon="#drawable/share" /></menu>
note i used app:showAsAction instead of android:showAsAction
You can add to your XML file the attribute android:showAsAction="always" inside your item element. It then will show the relevant menu option as an icon inside your action bar.
Note that it will be instead of the text in the menu.
For further read, look here under android:showAsAction.
/* menu 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">
<item android:id="#+id/one" android:title="one"
android:icon="#mipmap/ic_launcher" app:showAsAction="always" />
<item android:id="#+id/two" android:title="two"
android:icon="#mipmap/ic_launcher" app:showAsAction="always" />
<item android:id="#+id/three" android:title="three"
android:icon="#mipmap/ic_launcher" />
</menu>
/* Java code */
#SuppressLint("RestrictedApi")
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mymenu,menu);
if(menu instanceof MenuBuilder){
MenuBuilder m = (MenuBuilder) menu;
m.setOptionalIconsVisible(true);
}
return true;
}
Forget all those, do this step.
add app:showsAsAction="always" to your item. If you use android:showsAsAction="always" you won't get the solution.
Try with adding app attribute to your item.
I put explicit icons in onCreateOptionsMenu method using below code
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
if (item.getItemId() == R.id.print) {
item.setIcon(getDrawable(R.drawable.print));
}
}
Working with android.support.v7.app.AppCompatActivity, is making the input for the icons a very difficult task. You need to implement onMenuOpen, super method from AppComactActivity class. After this check, if the menu is not null. If the menu is not null pass Method class like this and setOptionalIconsVisible to true with boolean.
#Override
public boolean onMenuOpened(int featureId, Menu menu) {
if(menu != null){
if(menu.getClass().getSimpleName().equals("MenuBuilder")){
try{
Method m = menu.getClass().getDeclaredMethod(
"setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
}
catch(NoSuchMethodException e){
Log.e("MAIN", "onMenuOpened", e);
}
catch(Exception e){
throw new RuntimeException(e);
}
}
}
return super.onMenuOpened(featureId, menu);
}
Just add this attr inside item tag in your menu.xml
app:showAsAction="always
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 0, 0, "androidDemo").setIcon(R.drawable.ic_launcher);
getMenuInflater().inflate(R.layout.menu, menu);
return true;
}
and in xml:
<item android:id="#+id/menuUpdate"
android:icon="#drawable/update_icon"
android:title="#string/Update"
android:showAsAction="always"/>