onOptionsItemSelected not being called from within fragment - java

For some reason, my optionItemSelected is not being called when i click the button associated with it. The timber log is not called, but this appears in the logs the moment after i click the button:
D/ViewRootImpl#ba4d36e[POIHistoryFlowActivity]: ViewPostImeInputStage processPointer 0
D/ViewRootImpl#ba4d36e[POIHistoryFlowActivity]: ViewPostImeInputStage processPointer 1
Here is the code i have:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.activity_recent_destinations, menu);
Timber.d("Menu was inflated");
}
#Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_action_item_clear:
Timber.d("Clear button was clicked");
// clear the destinations
return true;
default:
return super.onOptionsItemSelected(item);
}
}
In similar fragments, the parent's activity does not override either onCreateOptionsItem() nor onOptionsItemSelected(), but their associated buttons work while in this fragment they do not and after combing through everything with the debugger I'm at a loss as to what the root cause could be. Any help would me super appreciated!
update:
activity_recent_destinations.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/menu_action_item_clear"
android:title="#string/menu_item_title_clear"
app:actionLayout="#layout/action_item_clear"
app:showAsAction="always" />
</menu>

You are using an "action layout" for this item. This is just going to act like a normal view and clicking on it won't trigger the onOptionsItemSelected callback. You have to get a reference to the layout itself and add a click listener:
#Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.activity_recent_destinations, menu);
MenuItem item = menu.findItem(R.id.menu_action_item_clear);
View actionView = item.getActionView();
// Set the listener on the root view or any children if necessary
actionView.setOnClickListener(...);
}

Related

Android search view not behaving right on toolbar

there you have the video that shows how my app actually behaves:
https://www.youtube.com/watch?v=81XIdEo0lks&feature=youtu.be
You see that when I click the search icon, it just moves it to the left side, then I need to click it again, then i need to click the x button 2 times before I actually get out of the search view, a complete mess.
Here's how I want my search view to behave:
https://www.youtube.com/watch?v=sJ-Z9G0SDhc&t
MainActivity.java (only the relevant part)
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
MenuItem searchItem = menu.findItem(R.id.app_bar_search);
SearchManager searchManager = (SearchManager) MainActivity.this.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = null;
if (searchItem != null) {
searchView = (SearchView) searchItem.getActionView();
}
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(MainActivity.this.getComponentName()));
}
return super.onCreateOptionsMenu(menu);
}
options_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/app_bar_search"
android:icon="#drawable/ic_search_black_24dp"
android:title="Search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.widget.SearchView" />
<item
android:id="#+id/logout_btn"
android:title="Log Out" />
</menu>
I want my search view to behave like the search view in that video, click on the search, the keyboard appears, you can type, you can exit. I also want to make this 3 vertical dots icon disappear when I enter the search view.
First declare a state variable to determine when menu item(s) needs to be hidden
boolean isHideMenuState = false;
Then reference the item(s) needed to be hidden inside onCreateOptionsMenu block
MenuItem logoutItem = menu.findItem(R.id.logout_btn);
//... initialize other menu items here
//use hidden state to define when to hide item(s)
if(isHideMenuState){
logoutItem.setVisible(false);
//by now the ellipses(...) should go off
//if not try using setShowAsAction passing (SHOW_AS_ACTION_NEVER)
}
else{
logoutItem.setVisible(true);
}
Next: Add focus change listener to your searchView
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
// Toggle isHideMenuState when search widget has focus/no focus
isHideMenuState = hasFocus
//Tell menu to re-create itself
invalidateOptionsMenu(); // onCreateOptionsMenu(...) is called again
}
});
And lastly for the UI try changing the actionViewClass of your searchView item
app:actionViewClass="android.support.v7.widget.SearchView"
click on the search, the keyboard appears, you can type, you can exit.
In order to do that, you need to do this:
in onCreateOptionsMenu:
add searchView.setIconifiedByDefault(false);
add
searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
searchView.setIconified(false);
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
searchView.setIconified(true);
searchView.clearFocus();
return true;
}
});
The purpose of searchView.setIconifiedByDefault(false); is to show the expanded view of SearchView by default when user pressed the search icon. The searchView.setIconified(false); is to let the view has focus and show the soft-keyboard. The searchView.setIconified(true); is to clear the text when your user exit from the SearchView. Lastly, the searchView.clearFocus(); is to hide the soft-keyboard.
I also want to make this 3 vertical dots icon disappear when I enter the search view.
For this, you can do this:
add logoutItem.setVisible(false); in onMenuItemActionExpand
add logoutItem.setVisible(true); in onMenuItemActionCollapse

Custom Action View layout not responding to menu item lisetener

I have created one custom action view layout using MenuItemCompat Java code is as shown in code below :
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem shoppingCartitem = menu.findItem(R.id.my_action_item_id);
shoppingCartitem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Log.v("MyAPP", "Listener called");
return true;
}
});
MenuItemCompat.setActionView(shoppingCartitem, R.layout.my_custom_action_view_layout);
return super.onCreateOptionsMenu(menu);
}
menu_main.xml as follows :
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="#+id/my_action_item_id"
android:icon="#drawable/ic_shopping_cart_white_24dp"
android:orderInCategory="9999"
android:title="#string/menu"
myapp:showAsAction="always" />
</menu>
What am I missing here, any suggestions ?
From the documentation:
Set a custom listener for invocation of this menu item. In most situations, it is more efficient and easier to use onOptionsItemSelected(MenuItem) or onContextItemSelected(MenuItem).
So you can simply override the onOptionsItemSelected callback, which is easier.
By the way to me your code seems to be right, but it doesn't do anything. Have you tried doing something like Log.v("MyAPP", "Listener called"); inside it?
EDIT:
I wrote this code:
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
MenuItem item = menu.findItem(R.id.my_action_item_id);
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Log.v("MyApp", "Inside listener");
return true;
}
});
MenuItemCompat.setActionView(item, R.layout.main_activity);
return super.onCreateOptionsMenu(menu);
}
}
main_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="#+id/my_action_item_id"
android:icon="#drawable/ic_launcher"
android:orderInCategory="9999"
android:title="Menu"
myapp:showAsAction="always" />
</menu>
And this is the result of the LogCat (I clicked the icon twice):
As you can see it works without problems
please try
MenuItem shoppingCartitem = menu.findItem(R.id.my_action_item_id);
change to
MenuItem shoppingCartitem = (MenuItem) findViewById(R.id.my_action_item_id);

Android Actionbar SearchView with item.getItemId() not working

i'm developing an application with API 8. now i'm trying to add 3 items in my menu, one
of item i added is SearchView, i used app:actionViewClass="android.support.v7.widget.SearchView" ofcourse to support the API 8,
and in my MainActivity class in onOptionsItemSelected(MenuItem item) i'm trying to handle the click on searchView, but it is no longer working.
how can fix this?
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">
<!--My SearchView--->
<item
android:id="#+id/menu_search"
android:orderInCategory="100"
android:title="#string/stringSearch"
app:actionViewClass="android.support.v7.widget.SearchView"
android:icon="#drawable/ic_magnify"
app:showAsAction="always"/>
<!--My Filter--->
<item
android:id="#+id/menu_filter"
android:orderInCategory="100"
android:icon="#drawable/ic_filter"
android:title="#string/StringFilter"
app:showAsAction="always" />
<!--Some menu--->
<item
android:id="#+id/menu_settings"
android:orderInCategory="100"
android:icon="#drawable/ic_dots"
android:title="#string/Settings"
app:showAsAction="always" />
</menu>
MainActivity.class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
...
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
//I setup the searchView here
MenuItem searchItem = menu.findItem(R.id.menu_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
....
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_search:
//This is click event on searchView but unfortunately not working
Toast.makeText(getApplicationContext(),"SearcView",Toast.LENGTH_LONG).show();
break;
case R.id.menu_settings:
Toast.makeText(getApplicationContext(),"Menu Settings",Toast.LENGTH_LONG).show();
break;
case R.id.menu_filter:
Toast.makeText(getApplicationContext(),"Menu Filter",Toast.LENGTH_LONG).show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
}
So, as you can see in my code, i try to fire a toast when the menu item is clicked, everything is working but not my SearchView.
this is happen when i started to add app:actionViewClass="android.support.v7.widget.SearchView" on menu in searchView item.
anyone can help me?
Thank you very much!
You'll want to use one of the listeners on the SearchView class. The OnSearchClickListener looks like it may be the right fit for you.
Edit. Here's a code example:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
MenuItem searchItem = menu.findItem(R.id.menu_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Handle clicks
}
});
return super.onCreateOptionsMenu(menu);
}

Android How to edit the Action bar menu from Fragment

I created an App that uses Fragment. From my MainActivity I set the ActionBar.
But in one of my Fragment I need to modify the action icons and on click.
So With the code below, when I load the my Fragment, it still display the action bar menu from MainActivity
here is my MainActivity :
public void restoreActionBar() {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
// enable ActionBar app icon to behave as action to toggle nav drawer
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
//Handle the Search Menu
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
searchView.setQueryHint(this.getString(R.string.action_search));
((EditText)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text))
.setHintTextColor(getResources().getColor(R.color.white));
searchView.setOnQueryTextListener(OnQuerySearchView);
mSearchCheck = false;
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}//end onCreateOptionsMenu
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
/** CAMERA **/
case R.id.action_camera:
//openCamera();
Utils.makeToast(getApplicationContext(), "Implement Camera", false);
return true;
/** SEARCH **/
case R.id.action_search:
//openSearch();
mSearchCheck = true;
Utils.makeToast(getApplicationContext(), "Implement Search", false);
return true;
/** SETTINGS **/
case R.id.action_settings:
//openSettings();
Utils.makeToast(getApplicationContext(), "Implement Settings", false);
return true;
/** ABOUT **/
case R.id.action_help:
//openHelp();
Utils.makeToast(getApplicationContext(), "Implement Help", false);
return true;
default:
return super.onOptionsItemSelected(item);
}//end switch
}//end onOptionsItemSelected
private OnQueryTextListener OnQuerySearchView = new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextChange(String arg0) {
// TODO Auto-generated method stub
if (mSearchCheck){
// implement your search here
}
return false;
}
};//end OnQueryTextListener
Here is the layout :
<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.example.sellbeesclean.MainActivity" >
<!-- CAMERA -->
<item
android:id="#+id/action_camera"
android:orderInCategory="100"
android:icon="#drawable/ic_action_camera"
android:title="#string/action_camera"
app:showAsAction="ifRoom|collapseActionView"/>
<!-- SEARCH -->
<item
android:id="#+id/action_search"
android:orderInCategory="100"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/>
<!-- SETTINGS -->
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never"/>
<!-- HELP -->
<item
android:id="#+id/action_help"
android:orderInCategory="100"
android:icon="#drawable/ic_action_help"
android:title="#string/action_help"
app:showAsAction="ifRoom|collapseActionView"/> </menu>
Her is my Fragment :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
View rootView = inflater.inflate(R.layout.user_profile_fragment, container, false);
Log.i(TAG, "onCreateView");
.....
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
/** EDIT **/
case R.id.action_edit:
//openEditProfile(); //Open Edit Profile Fragment
Utils.makeToast(MyApplication.getAppContext(), "Implement Camera", false);
return true;
default:
return super.onOptionsItemSelected(item);
}//end switch
}//end onOptionsItemSelected
here the fragment menu layout
<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.example.sellbeesclean.MainActivity" >
<!-- EDIT -->
<item
android:id="#+id/action_edit"
android:orderInCategory="100"
android:icon="#drawable/ic_action_edit"
android:title="#string/action_edit_profile"
app:showAsAction="ifRoom|collapseActionView"/></menu>
In your fragment's onCreateView method write
setHasOptionsMenu(true);
And inflate your menu xml file in onCreateOptionsMenu method
In onCreateOptionsMenu of a fragment, write
menu.clear();
before inflating menus

Creating a New button Android

I am trying to create a New button (icon only) next to the 3 dots button in the ActionBar. This is the code I tried, but it adds it as child of the 3 dots button.
main_activity_actions.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/create_game"
android:menuCategory="container"
android:orderInCategory="1"
android:title="#string/new_game"
android:titleCondensed="nieuw spel">
</item>
</menu>
MainActivity.java:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return true;
}
Also, how can I find out what default icons I can use?
To show icons in the action bar, you can add the line android:showAsAction="always" to your XML item. Still Android would show it only if it judges there is adequate space in the action bar. If you strictly always want to show your button, you can define and set a custom layout for your action bar.
You can download the default icon set for action bar from https://developer.android.com/design/downloads/index.html
try it
/res/menu/activity_main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_settings"
android:showAsAction="never"
android:title="#string/menu_settings"/>
<item
android:id="#+id/menu_save"
android:showAsAction="ifRoom"
android:icon="#android:drawable/ic_menu_save"
android:title="#string/menu_guardar"/>
<item
android:id="#+id/menu_new"
android:showAsAction="ifRoom|withText"
android:icon="#android:drawable/ic_menu_add"
android:title="#string/menu_nuevo"/>
</menu>
MainActivit.class
public class MainActivity extends Activity {
//...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
//onClic item
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new:
Log.i("ActionBar", "Nuevo!");
return true;
case R.id.menu_save:
Log.i("ActionBar", "Guardar!");;
return true;
case R.id.menu_settings:
Log.i("ActionBar", "Settings!");;
return true;
default:
return super.onOptionsItemSelected(item);
}
}
And you can download All IconPack here:
https://developer.android.com/design/downloads/index.html
Yes, you can inflate a custom actionbar for adding buttons with images like this:
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) getActionBar()
.getThemedContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
View customActionBarView = inflater.inflate(R.layout.actionbar_custom, null);
ActionBar actionBar = getActionBar();
actionBar.setDisplayOptions(
ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
actionBar.setCustomView(customActionBarView,
new ActionBar.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
setContentView(R.layout.activity_main);
}
Where _actionbar_custom.xml_ would be your layout resource, usually a LinearLayout with whatever components you want.

Categories