I know that this question has already been asked, but none of the proposed solutions work for me.
I want this method to be called from the Fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState) {
View view = inflater.inflate(R.layout.my_clock_layout, container, false);
listView = (ListView) view.findViewById(R.id.clock_list);
listView.setAdapter(new ClockAdapter(this.getActivity()));
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.add_alarm:
Fragment newContent = new AddAlarmFragment();
if (getActivity() instanceof MenuMainActivity) {
MenuMainActivity mma = (MenuMainActivity) getActivity();
mma.switchContent(newContent);
}
}
return super.onOptionsItemSelected(item);
}
}
And then in the MenuMainActivity this method gets called:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
toggle();
return true;
case R.id.add_alarm:
return false;
}
return super.onOptionsItemSelected(item);
}
This unfortunately, is not working and the Fragment method doesn't get called.
What might the problem be?
Thanks in advance!
In your fragments onCreate make sure you're calling setHasOptionsMenu(true);
EDIT Please make sure your public boolean onOptionsItemSelected(MenuItem item) is actually public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item). Or update the import to this MenuItem
So I found my mistake. My Activity was extending a SherlockFragmentActivity, but the Fragment was extending normal Fragment instead of SherlockFragment. With the Fragment extending SherlockFragment it works now.
Thanks for help everyone!
Related
My Fragment class:
Toolbar toolbar;
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
toolbar = getView().findViewById(R.id.toolbar3);
toolbar.inflateMenu(R.menu.menufragmentmain);
setHasOptionsMenu(true); //i also tried putting this function in oncreate function
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Toast.makeText(getActivity(), "i never enter this function also" , Toast.LENGTH_LONG).show();
super.onCreateOptionsMenu(menu,inflater);
inflater.inflate(R.menu.menufragmentmain, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Toast.makeText(getActivity(), "i never enter this function" , Toast.LENGTH_LONG).show();
//some switch cases.....
return super.onOptionsItemSelected(item);
}
I've got a stupid error which I cant find unfourtantly. I've got a simple toolbar for my fragment. In onViewCreated I inflate my actionbar menu with my toolbar.
The issue is that the functions onCreateOptionsMenu and 'onOptionsItemSelected' are never called. I've got no clue why.
Things i checked in other similar questions with the same issue:
I checked if my main activity has a onCreateOptionsMenu or'onOptionsItemSelected'. It doesn*t
Checked if my style class has NOT: android:theme="#android:style/Theme.Black.NoTitleBar
None of the points unfourtantly work. What did I miss. Do I need to check something else?
As per the Fragment-owned app bar guide which explains how to use a Fragment-owned Toolbar, you do not use any of the setHasOptionsMenu(), onCreateOptionsMenu(), or onOptionsItemSelected() APIs - those are only used for activity owned app bars.
Instead, you would follow the guide for handling menu click events by using the Toolbar APIs:
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
toolbar = getView().findViewById(R.id.toolbar3);
toolbar.inflateMenu(R.menu.menufragmentmain);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(getActivity(), "onMenuItemClick called" , Toast.LENGTH_LONG).show();
//some switch cases.....
return true;
}
});
}
Set up the toolbar in the host Activity. Then override the menu handling in each Fragment wherever necessary.
Here's some generic scaffolding (with comments):
public class MyFragment extends Fragment {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Report that this Fragment has an options menu
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
// Inflate then menu, and THEN call super()
// Note the order of the invocations
inflater.inflate(R.menu.my_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
// Handle menu item selections
final int itemId = item.getItemId();
switch(itemId) {
case R.id.my_menu_option_x: ...; return true;
case R.id.my_menu_option_y: ...; return true;
case R.id.my_menu_option_z: ...; return true;
default: return super.onOptionsItemSelected(item);
}
}
}
I have an app that has 4 (0,1,2,3) Tabs and Fragments. My Actionbar has a menu item called "settings". When settings is clicked I want to navigate from the current Tab/Fragment to Fragment(3). In each of my java files associated with a fragment I am using the code below to handle menu clicks. I can launch an Intent successfully with this code but how can I navigate to another tab/fragment on menu item click? Thanks!
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
My actual code.
public class event extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.event, container, false);
setHasOptionsMenu(true);
return view;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.notify:
Log.i("4", "Notify pressed");
return true;
case R.id.action_settings:
Log.i("4", "Settings pressed");
return true;
default:
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.custom_menu, menu);
}
}
If you're using a ViewPager then it's as simple as setCurrentItem(int currentItem)
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
// ...
case R.id.settings:
((ViewPager)findViewById(R.id.of_view_pager)).setCurrentItem(3);
return true;
// ...
}
}
Edit in response to:
When I add that code some elements show up in red indicating I am doing something wrong. "findViewById" and "of_view_pager" are in red.
Sounds like you are in a Fragment and not an Activity in which case you probably want to find the ViewPager in your onCreateView method and store it in a field for later use in your onOptionsItemSelected method.
Something like this:
private ViewPager m_viewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_changelog, container, false);
// Other stuff already in your `onCreateView`
m_viewPager = (ViewPager) view.findViewById(R.id.of_view_pager);
return view;
}
The of_view_pager is in red because that id doesn't exist. You need to replace it with the correct id of your ViewPager that you specified in the layout.
Ok, I know where I went wrong. I had a main activity and a fragment for each tab in my application. I had two action bar menus one included in the main activity and one custom menu for fragments. The code I was trying to run for switching tabs by clicking a menu button did not work if the onOptionsItemSelected code was in the fragment file. When I put the code in the main activity it worked fine.
I'm trying to add a button to my menu bar in my ListFragment class. When I click the button, nothing happens though. The onCreateOptionsMenu method is never being called in the class. I've tried everything to get it working but it still won't work. Has anyone got any solutions?
I've attached my code below:
public class FragmentZero extends ListFragment {
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// use your custom layout
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout_zero, container, false);
oslist = new ArrayList<HashMap<String, String>>();
new JSONParse().execute();
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu items for use in the action bar
inflater.inflate(R.menu.main_fragment_zero, menu);
super.onCreateOptionsMenu(menu, inflater);
}
public boolean onOptionsItemsSelected(MenuItem item) {
// Take appropriate action for each action item click
switch (item.getItemId()) {
case R.id.action_refresh:
// check for updates action
RefreshButton();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Add setHasOptionsMenu(true) to your onCreateView() method and remove it in OnCreate().
So this was a pretty stupid error that I was having and I solved it thanks to everyone's help here.
I was spelling onOptionItemSelected wrong. I was adding an extra 's' after item.
As soon as I corrected this, the method started to work.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
RefreshButton();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void RefreshButton() {
oslist = new ArrayList<HashMap<String, String>>();
new JSONParse().execute();
}
I know this question has been asked and but I am unable to solve my problem after looking at those answer. I have an Activity with a Fragment.
In fragment, I have added the toolbar and I want to handle toolbar menu item click events from the fragments.
In menu, I have added a single share button. I am getting the click event callback for the Up navigation (arrow home button) but I am not getting click event callback for the share button in my fragment.
Can some points me at what I am doing wrong here.
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"
tools:context="com.rahul.haridasasampada.details.DescriptionActivity">
<item
android:id="#+id/action_share"
android:title="Share"
android:orderInCategory="100"
app:showAsAction="always"
app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
</menu>
I have added toolbar to the fragment layout.
My Activity's code -
public class DescriptionActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_description);
if (savedInstanceState == null) {
Article articleExtra = (Article) getIntent().getParcelableExtra(DescriptionFragment.ARGS_EXTRA);
DescriptionFragment descriptionFragment = DescriptionFragment.newInstance(articleExtra);
getSupportFragmentManager().beginTransaction()
.add(R.id.container, descriptionFragment)
.commit();
}
}
#Override
protected void onResume() {
super.onResume();
getSupportActionBar().setTitle(R.string.app_name_in_kannada);
}
#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_description, menu);
Log.d("debug", "activity : onCreateOptionsMenu");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
Log.d("debug","activity: action home has clicked");
onBackPressed();
return false;
case R.id.action_share:
Log.d("debug","activity: action share has clicked");
return false;
}
return super.onOptionsItemSelected(item);
}
}
My Fragments code -
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
// some code
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ActionBarActivity actionBarActivity = (ActionBarActivity) getActivity();
Toolbar toolbar = (Toolbar) getView().findViewById(R.id.toolbar_actionbar);
actionBarActivity.setSupportActionBar(toolbar);
toolbar.setOnMenuItemClickListener(this);
toolbar.inflateMenu(R.menu.menu_description);
}
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_share:
if (menuItem.getItemId() == R.id.action_share)
Log.d("debug","action share has clicked");
return true;
}
return false;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
Log.d("debug", "fragment : onCreateOptionsMenu");
MenuItem shareMenuItem = menu.findItem(R.id.action_share);
mShareActionProvider =(ShareActionProvider)MenuItemCompat.getActionProvider(shareMenuItem);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
Log.d("debug","fragment : action home has clicked");
return true;
case R.id.action_share:
Log.d("debug","fragment: action share has clicked");
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View detailFragmentView = inflater.inflate(R.layout.fragment_description, null);
return detailFragmentView;
}
From Android Docs, for Fragment:
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater)
Initialize the contents of the Activity's standard options menu. You should place your menu items in to menu. For this method to be called, you must have first called setHasOptionsMenu(boolean).
so you want to control actionbar menu in Fragment, then you have to call setHasOptionsMenu method better in Fragment's onCreate(...):
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
also important is that you should not use inflateMenu and onCreateOptionsMenu both together for same ToolBar, inflateMenu is for standalone without setting ToolBar as ActionBar.
Suggestion:
keep one ToolBar in Activity as ActionBar for your App, and another ToolBar standalone inside Fragment.
Hope this help!
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
public class MyFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list, container, false);
Toolbar toolbar= (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.menu_main);
toolbar.setOnMenuItemClickListener(this);
return rootView;
}
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_menu:
//do sth here
return true;
}
return false;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.training1_fragment, container,
false);
setHasOptionMenu(true);
return v;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save :
{
//Write here what to do you on click
return true;
}
}
return super.onOptionsItemSelected(item);
}
You should getPointer toolbar from your activity class and inflate menu in fragment class.
You can look this ex:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
activity = ((DescriptionActivity ) getActivity());
Toolbar tollbar=getView.findViewById(R.id.your_toolbar);
activity.setSupportActionBar(toolbar);
activity.toolbar.inflateMenu(R.menu.menu_search);
activity.toolbar.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_search:
break;
}
return false;
}
Please refer this for click of the Fragment optionMenu click link.
Is it permitted to call SherlockFragmentActivity.supportInvalidateOptionsMenu from SherlockFragment.onCreateView? I couldn't find anything saying otherwise, but it seems like doing so may cause clicks on the menu items to not be handled until one exits the activity. (This happens on an API 8 emulator).
I have a fairly simple repro of this behavior. For some reason, it only happens when the activity did not add any menu items, but the fragment did.
Following is the code of the repro, if anyone is interested. What will happen is, the background will not turn red. However, if you comment out getSherlockActivity().supportInvalidateOptionsMenu(), it does turn red.
public class MainActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frag_container);
FunFragment frag = new FunFragment();
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.add(R.id.frag_container, frag, "foobar");
trans.commit();
}
}
public class FunFragment extends SherlockFragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getSherlockActivity().supportInvalidateOptionsMenu();
return new View(getActivity());
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add(0, 5, 0, "Do magic").setIcon(R.drawable.ic_launcher)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 5:
getView().setBackgroundDrawable(new ColorDrawable(0xFFFF0000));
return true;
default:
return false;
}
}
}
You can just call invalidateOptionsMenu() instead of supportInvalidateOptionsMenu().